docs(acp): clarify default startup and runtime paths

This commit is contained in:
Peter Steinberger 2026-04-04 15:10:07 +09:00
parent e56ffd48df
commit b32a2cadc2
No known key found for this signature in database
6 changed files with 98 additions and 5 deletions

View File

@ -21,6 +21,24 @@ If you want an external MCP client to talk directly to OpenClaw channel
conversations instead of hosting an ACP harness session, use
[`openclaw mcp serve`](/cli/mcp) instead.
## What this is not
This page is often confused with ACP harness sessions.
`openclaw acp` means:
- OpenClaw acts as an ACP server
- an IDE or ACP client connects to OpenClaw
- OpenClaw forwards that work into a Gateway session
This is different from [ACP Agents](/tools/acp-agents), where OpenClaw runs an
external harness such as Codex or Claude Code through `acpx`.
Quick rule:
- editor/client wants to talk ACP to OpenClaw: use `openclaw acp`
- OpenClaw should launch Codex/Claude/Gemini as an ACP harness: use `/acp spawn` and [ACP Agents](/tools/acp-agents)
## Compatibility Matrix
| ACP area | Status | Notes |

View File

@ -20,6 +20,10 @@ rate-limited, or temporarily misbehaving. This is intentionally conservative:
This is designed as a **safety net** rather than a primary path. Use it when you
want “always works” text responses without relying on external APIs.
If you want a full harness runtime with ACP session controls, background tasks,
thread/conversation binding, and persistent external coding sessions, use
[ACP Agents](/tools/acp-agents) instead. CLI backends are not ACP.
## Beginner-friendly quick start
You can use Claude Code CLI **without any config** (the bundled Anthropic plugin

View File

@ -19,6 +19,36 @@ If you want Codex or Claude Code to connect as an external MCP client directly
to existing OpenClaw channel conversations, use [`openclaw mcp serve`](/cli/mcp)
instead of ACP.
## Which page do I want?
There are three nearby surfaces that are easy to confuse:
| You want to... | Use this | Notes |
| ---------------------------------------------------------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Run Codex, Claude Code, Gemini CLI, or another external harness _through_ OpenClaw | This page: ACP agents | Chat-bound sessions, `/acp spawn`, `sessions_spawn({ runtime: "acp" })`, background tasks, runtime controls |
| Expose an OpenClaw Gateway session _as_ an ACP server for an editor or client | [`openclaw acp`](/cli/acp) | Bridge mode. IDE/client talks ACP to OpenClaw over stdio/WebSocket |
| Reuse a local AI CLI as a text-only fallback model | [CLI Backends](/gateway/cli-backends) | Not ACP. No OpenClaw tools, no ACP controls, no harness runtime |
## Does this work out of the box?
Usually, yes.
- Fresh installs now ship the bundled `acpx` runtime plugin enabled by default.
- The bundled `acpx` plugin prefers its plugin-local pinned `acpx` binary.
- On startup, OpenClaw probes that binary and self-repairs it if needed.
- Start with `/acp doctor` if you want a fast readiness check.
What can still happen on first use:
- A target harness adapter may be fetched on demand with `npx` the first time you use that harness.
- Vendor auth still has to exist on the host for that harness.
- If the host has no npm/network access, first-run adapter fetches can fail until caches are pre-warmed or the adapter is installed another way.
Examples:
- `/acp spawn codex`: OpenClaw should be ready to bootstrap `acpx`, but the Codex ACP adapter may still need a first-run fetch.
- `/acp spawn claude`: same story for the Claude ACP adapter, plus Claude-side auth on that host.
## Fast operator flow
Use this when you want a practical `/acp` runbook:
@ -70,6 +100,26 @@ Use ACP when you want an external harness runtime. Use sub-agents when you want
See also [Sub-agents](/tools/subagents).
## How ACP runs Claude Code
For Claude Code through ACP, the stack is:
1. OpenClaw ACP session control plane
2. bundled `acpx` runtime plugin
3. Claude ACP adapter
4. Claude-side runtime/session machinery
Important distinction:
- ACP Claude is not the same thing as the direct `claude-cli/...` fallback runtime.
- ACP Claude is a harness session with ACP controls, session resume, background-task tracking, and optional conversation/thread binding.
- `claude-cli/...` is a text-only local CLI backend. See [CLI Backends](/gateway/cli-backends).
For operators, the practical rule is:
- want `/acp spawn`, bindable sessions, runtime controls, or persistent harness work: use ACP
- want simple local text fallback through the raw CLI: use CLI backends
## Bound sessions
### Current-conversation binds
@ -614,7 +664,17 @@ See [Configuration Reference](/gateway/configuration-reference).
## Plugin setup for acpx backend
Install and enable plugin:
Fresh installs ship the bundled `acpx` runtime plugin enabled by default, so ACP
usually works without a manual plugin install step.
Start with:
```text
/acp doctor
```
If you disabled `acpx`, denied it via `plugins.allow` / `plugins.deny`, or want
to switch to a local development checkout, use the explicit plugin path:
```bash
openclaw plugins install acpx

View File

@ -1,5 +1,6 @@
{
"id": "acpx",
"enabledByDefault": true,
"name": "ACPX Runtime",
"description": "ACP runtime backend powered by acpx with configurable command path and version policy.",
"skills": ["./skills"],

View File

@ -250,7 +250,7 @@ describe("collectPluginConfigAssignments", () => {
);
});
it("keeps bundled acpx inactive unless explicitly enabled", () => {
it("treats bundled acpx as active by default", () => {
const config = asConfig({
plugins: {
enabled: true,
@ -274,9 +274,11 @@ describe("collectPluginConfigAssignments", () => {
loadablePluginOrigins: loadablePluginOrigins([["acpx", "bundled"]]),
});
expect(context.assignments).toHaveLength(0);
expect(context.assignments).toHaveLength(1);
expect(context.assignments[0]?.path).toBe("plugins.entries.acpx.config.mcpServers.s1.env.K");
expect(context.assignments[0]?.ref.id).toBe("K");
expect(context.warnings.some((w) => w.code === "SECRETS_REF_IGNORED_INACTIVE_SURFACE")).toBe(
true,
false,
);
});

View File

@ -9,6 +9,7 @@ import {
import { isRecord } from "./shared.js";
const ACPX_PLUGIN_ID = "acpx";
const ACPX_ENABLED_BY_DEFAULT = true;
/**
* Walk plugin config entries and collect SecretRef assignments for MCP server
@ -63,7 +64,14 @@ export function collectPluginConfigAssignments(params: {
continue;
}
const enableState = resolveEnableState(pluginId, pluginOrigin ?? "config", normalizedConfig);
const enableState = resolveEnableState(
pluginId,
pluginOrigin ?? "config",
normalizedConfig,
pluginId === ACPX_PLUGIN_ID && pluginOrigin === "bundled"
? ACPX_ENABLED_BY_DEFAULT
: undefined,
);
collectMcpServerEnvAssignments({
pluginId,
pluginConfig,