Skip to content

acp editors

Mike Crowe edited this page Oct 24, 2026 · 3 revisions

Using harnessed from an editor (ACP)

Note

ACP support for claude and omp is complete in host mode and container mode (#528). Host mode is verified in Zed and Atlas. Container mode is verified in Zed; it has not been tested in Atlas.

An editor that speaks the Agent Client Protocol (ACP) can run a harnessed stack as its coding agent. You get the stack's skills, rules, MCP servers, and settings inside the editor's agent panel, with the same isolated config dir that host-run uses. Nothing is installed into the editor's own config beyond one entry that names a command.

How it works

ACP is newline-delimited JSON-RPC over stdio. The editor starts the agent as a child process, writes requests to its stdin, and reads replies from its stdout. harnessed writes one launcher per stack and harness that speaks this protocol, so the editor needs only a command:

~/.local/bin/harnessed-acp-<harness>-<stack>-<backend>
  • <harness> is claude or omp. These are the two harnesses with an ACP mode. omp has one built in. claude runs through the claude-agent-acp adapter.
  • <stack> is any stack you have built.
  • <backend> is host or container (see the next section).

One launcher serves every project you open. The editor names the project folder when it starts a session (the cwd of ACP's session/new), and harnessed runs that session in that folder. You do not need one editor entry per project.

Host or container

host container
Where the agent runs On your machine, in the project folder In a podman pod
Project folder Taken from each session, so one entry works everywhere Taken from each session's session/new cwd, so one entry works everywhere
Egress firewall Not enforced. The agent can reach anything your machine can Enforced
Ready for editors Yes Yes

Host mode isolates configuration, not the filesystem, exactly like host-run. The agent works in your real project with your real credentials. If you need the container boundary, use a -container launcher.

Before you start

  1. Install harnessed as in Getting started.

  2. Build the stack for the harness. This assembles the profile and writes the launchers into ~/.local/bin:

    harnessed build mine claude

    A stale or missing profile makes the agent exit before the editor's handshake, and the editor shows only "failed to launch". Build again after you change the stack.

  3. For claude, install the ACP adapter. harnessed build <stack> claude offers to install the pinned version of @agentclientprotocol/claude-agent-acp. Accept, or run the install command it prints with your own package manager. Without it, the claude launcher exits with an error that names the install command. A different version runs with a warning.

  4. Check the launcher outside the editor. Send one initialize request. A JSON reply that contains "result" means the agent is ready:

    cd /tmp
    echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{}}}' \
      | ~/.local/bin/harnessed-acp-claude-mine-host

    Launch messages go to stderr. Only JSON-RPC goes to stdout.

harnessed install <stack> <harness> rewrites the launchers without a build. Run it after you upgrade harnessed, so that every launcher points at the current install.

Use the full path to the launcher in editor settings. An editor started from a desktop launcher often has a short PATH that does not include ~/.local/bin.

Zed

Add an entry under agent_servers in ~/.config/zed/settings.json. The key is the name Zed shows in the agent panel:

{
  "agent_servers": {
    "harnessed claude (mine)": {
      "type": "custom",
      "command": "/home/you/.local/bin/harnessed-acp-claude-mine-host",
      "args": [],
      "env": {}
    },
    "harnessed omp (mine)": {
      "type": "custom",
      "command": "/home/you/.local/bin/harnessed-acp-omp-mine-host",
      "args": [],
      "env": {}
    }
  }
}

Open the agent panel, start a new thread, and pick the entry. To see the protocol traffic and the agent's stderr, run dev: open acp logs from the command palette.

For container mode, use a -container launcher, ~/.local/bin/harnessed-acp-<harness>-<stack>-container. Leave args empty: do not put a project path there. One entry serves every project you open, and each project gets its own agent. For example, harnessed-acp-claude-default-container runs claude on the default stack, and harnessed-acp-omp-zai-acp-container runs omp on the zai-acp stack:

{
  "agent_servers": {
    "harnessed claude (default, container)": {
      "type": "custom",
      "command": "/home/you/.local/bin/harnessed-acp-claude-default-container",
      "args": [],
      "env": {}
    },
    "harnessed omp (zai-acp, container)": {
      "type": "custom",
      "command": "/home/you/.local/bin/harnessed-acp-omp-zai-acp-container",
      "args": [],
      "env": {}
    }
  }
}

Atlas

Atlas has no settings screen for custom agents. Add the entry to its installed-agents file by hand:

  1. Quit Atlas. It rewrites the file on every agent install and uninstall, so an edit made while it runs can be lost.

  2. Edit ~/.local/share/dev.atlas.ide/external-agents/installed.json. A development build of Atlas uses ~/.local/share/dev.atlas.ide.dev/external-agents/installed.json instead. Create the file if it does not exist.

    {
      "harnessed claude (mine)": {
        "type": "custom",
        "command": "/home/you/.local/bin/harnessed-acp-claude-mine-host",
        "args": []
      }
    }

    Keep any entries that are already there. The key is the display name.

  3. Keep the JSON valid. Atlas treats a malformed file as empty. jq . installed.json is a quick check.

  4. Start Atlas and pick the agent.

Atlas writes the agent's stderr into its own log as agent stderr: lines.

VS Code and other editors

Any editor or client that lets you set a custom agent command works the same way: give it the launcher path, no arguments.

  • VS Code has no built-in way to add an ACP agent. The Agents window lists a fixed set of agents and cannot take a custom command. ACP client extensions such as ACP Client accept one. We have not tested harnessed with them yet.
  • Clients that pick from a fixed list of agents, such as the aoe structured view, cannot use these launchers.

What happens when a session starts

  1. The editor starts the launcher once. harnessed answers initialize and waits. The folder the editor starts it in gets only the per-stack setup.
  2. The editor sends session/new with a project folder. The first session in a folder runs that project's setup there: the stack's services, the project tool environment, and each recipe's setup and init scripts. This is the same per-project setup that host-run does.
  3. The agent runs in that folder with the stack's config dir. Later sessions in the same folder skip the setup.

In container mode, the first session in a project also waits for that project's pod to start. harnessed answers initialize at once, but the editor's session/new request gets its reply only after the agent in the pod is up. If the pod starts slowly, the editor's time limit for session/new can run out before the agent is ready. Later sessions in the same project use the same agent.

Recipe init scripts can write files into the project, as they do under host-run.

If the stack declares secrets, harnessed resolves them when the agent starts. If they cannot be resolved, the agent still starts without them, and the error appears in the editor's agent log. Check that log first when a tool that needs a key fails.

Troubleshooting

  • "Failed to launch" or the agent exits at once. Run the initialize check from Before you start in a terminal. The error it prints on stderr is the one the editor hides. The usual causes are an unbuilt stack and a missing claude adapter.
  • "No such command 'host-acp'". The launcher predates the fix that made launchers call harnessed by absolute path (#574), and found an older harnessed on PATH. Run harnessed install <stack> <harness> to rewrite it.
  • The session runs in the wrong folder. Check that the editor entry has empty args. A -container launcher takes the folder from the editor's session/new, unless a path in args names the project instead.
  • omp hangs on the first prompt. omp's model provider must be reachable and signed in for that stack. Test it with harnessed host-run omp --stack <stack> in a terminal first.

Known limits

  • A version change makes the profile stale. The build stamp includes the harnessed version. When the harnessed that launches the agent differs from the one that built the profile, for example a release install and a source checkout, the profile counts as stale. Run harnessed build <stack> <harness> with the harnessed that launches it.
  • omp needs egress to its model's API. In container mode the egress firewall applies, so omp needs a stack that allows its model provider. For example, omp's zai model needs api.z.ai, which the zai-acp stack allows and default does not.
  • Host mode has no network boundary. A stack's egress allowlist is not enforced, and harnessed prints a notice saying so at launch.
  • Editor setup is manual. Integrations that write the editor entries for you are tracked in #569.

Clone this wiki locally