Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions openhands/usage/agent-canvas/acp-agents.mdx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: ACP Agents
title: Bring Your Own Agent
description: Drive Agent Canvas conversations with an external coding agent — Claude Code, Codex, or Gemini CLI — over the Agent Client Protocol.
---

Agent Canvas can drive your conversations with the built-in **OpenHands** agent or with an external **ACP agent** — Claude Code, Codex, or Gemini CLI. This guide explains what ACP agents are, how to onboard one, and how to switch agents or models later.

## What is an ACP agent?
## What is an ACP Agent?

The [Agent Client Protocol (ACP)](https://agentclientprotocol.com/protocol/overview) is a standard for talking to coding agents over JSON-RPC on stdio. Instead of Agent Canvas calling an LLM directly, the Agent Server spawns the agent's own CLI as a subprocess and relays each turn to it. The external agent manages its own LLM, tools, and execution; Agent Canvas sends messages and renders what comes back.

Check warning on line 10 in openhands/usage/agent-canvas/acp-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

openhands/usage/agent-canvas/acp-agents.mdx#L10

Did you really mean 'subprocess'?

```mermaid
flowchart LR
Expand All @@ -21,18 +21,18 @@
acp -- "API calls" --> llm
```

The Agent Server owns the subprocess and the credentials; Agent Canvas only records *which* agent to run and surfaces a form for the secrets it needs. The agent choice is stored per backend, so switching backends can switch agents.

Check warning on line 24 in openhands/usage/agent-canvas/acp-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

openhands/usage/agent-canvas/acp-agents.mdx#L24

Did you really mean 'subprocess'?

## Supported providers
## Supported Providers

The provider list is sourced from the SDK registry (`openhands.sdk.settings.acp_providers`, mirrored into `@openhands/typescript-client`) and enriched with Canvas UI metadata. Adding or changing a provider happens upstream in the SDK, not in Agent Canvas.

| Provider | Default command |
|---|---|
| **Claude Code** | `npx -y @agentclientprotocol/claude-agent-acp` |
| **Codex** | `npx -y @zed-industries/codex-acp` |
| **Gemini CLI** | `npx -y @google/gemini-cli --acp` |

The provider list is sourced from the OpenHands SDK registry (`openhands.sdk.settings.acp_providers`, mirrored into `@openhands/typescript-client`) and enriched with Canvas UI metadata. Adding or changing a provider happens upstream in the SDK.

## Authentication

<Info>
Expand All @@ -43,49 +43,49 @@

| Provider | Subscription login (auto-detected) | API key |
|---|---|---|
| **Claude Code** | A Claude Code login (Pro/Max), from Claude Code's own credential store: the **macOS Keychain**, or `~/.claude/.credentials.json` on Linux | `ANTHROPIC_API_KEY` |
| **Codex** | A ChatGPT login (`codex login`) cached at `~/.codex/auth.json` | `OPENAI_API_KEY` |
| **Gemini CLI** | Your Google login (`gemini`/`gemini --acp`) cached at `~/.gemini/oauth_creds.json` | `GEMINI_API_KEY` |
| **Claude Code** | A Claude Code login (Pro/Max), from Claude Code's own credential store: the **macOS Keychain**, or `~/.claude/.credentials.json` on Linux | `ANTHROPIC_API_KEY` *(onboarding)* |
| **Codex** | A ChatGPT login (`codex login`) cached at `~/.codex/auth.json` | `OPENAI_API_KEY` *(onboarding)* |
| **Gemini CLI** | Your Google login (`gemini`/`gemini --acp`) cached at `~/.gemini/oauth_creds.json` | `GEMINI_API_KEY` *(onboarding)* |

All three collect an *optional* API key (plus base URL) in onboarding. As noted above, a subscription / OAuth login takes priority over an API key — when the provider's CLI is signed in, a key set in the environment is not used:

- **Codex** — `codex login status` keeps reporting the ChatGPT login even with `OPENAI_API_KEY` set.
- **Gemini CLI** — uses the OAuth auth type chosen at `gemini` login; `GEMINI_API_KEY` is only consulted if you switch the auth type. The free Google login is the common no-key path locally — sign in once and it just works.
- **Claude Code** — with both present, `claude auth status` reports it is authenticated via the subscription (`claude.ai`), not the key. The login is auto-detected from the macOS Keychain (or `~/.claude/.credentials.json` on Linux); `CLAUDE_CONFIG_DIR` is **not** required for it — it only relocates Claude Code's config directory (settings/history, not the token) and signals the SDK to strip a conflicting `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL`.
- **Claude Code** — with both present, `claude auth status` reports it is authenticated via the subscription (`claude.ai`), not the key. The login is auto-detected from the macOS Keychain (or `~/.claude/.credentials.json` on Linux); `CLAUDE_CONFIG_DIR` is **not** required for it — it only relocates Claude Code's config directory (settings/history, not the token; e.g. for containers or multiple accounts) and signals the SDK to strip a conflicting `ANTHROPIC_API_KEY` / `ANTHROPIC_BASE_URL`.

The one exception is the **base URL** (`*_BASE_URL`): a custom value points the CLI at a different endpoint (a proxy or gateway) and *does* take effect even under a login — for Gemini it rides the ACP `gateway` param. It's an advanced override, not needed for normal use.

Check warning on line 56 in openhands/usage/agent-canvas/acp-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

openhands/usage/agent-canvas/acp-agents.mdx#L56

Did you really mean 'param'?

## Onboarding an ACP agent
## Onboarding an ACP Agent

First-time users get a four-step onboarding modal. To onboard an ACP agent:

1. **Choose agent** — pick Claude Code, Codex, or Gemini CLI instead of OpenHands. The choice is saved immediately to your backend's settings.

Check warning on line 62 in openhands/usage/agent-canvas/acp-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

openhands/usage/agent-canvas/acp-agents.mdx#L62

Did you really mean 'backend's'?
2. **Check backend** — confirms Agent Canvas can reach the Agent Server.
3. **Set up credentials** — enter the provider's API key (and, optionally, a custom base URL for a proxy or gateway). All three providers collect these here, and every field is optional.
3. **Set up credentials** — enter the provider's API key (and, optionally, a custom base URL for a proxy or gateway). All three providers — Claude Code, Codex, and Gemini CLI — collect these here, and every field is optional.
4. **Say hello** — creates your first conversation and closes the modal.

<Note>
Every credential field is optional and the step is skippable. Leave a field blank to reuse a key already set on the backend, or to authenticate the agent through a subscription / OAuth login instead.

Check warning on line 68 in openhands/usage/agent-canvas/acp-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

openhands/usage/agent-canvas/acp-agents.mdx#L68

Did you really mean 'skippable'?
</Note>

### How credentials reach the agent
### How Credentials Reach the Agent

Each credential you enter is saved as a **global secret** whose name is exactly the environment variable the Agent Server exports into the ACP subprocess (e.g. `ANTHROPIC_API_KEY`). Saving in onboarding is identical to adding the secret under **Settings → Secrets**, where you can edit or remove it anytime. Keeping the secret name equal to the env var is what makes a saved key actually reach the provider CLI.

Check warning on line 73 in openhands/usage/agent-canvas/acp-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

openhands/usage/agent-canvas/acp-agents.mdx#L73

Did you really mean 'subprocess'?

## Switching agent or model later
## Switching Agent or Model Later

Open **Settings → Agent** at any time:

- **Agent** — switch between **OpenHands** and **ACP**.
- **Preset** — pick a built-in provider (Claude Code, Codex, Gemini CLI) or **Custom** to point at any other ACP server.
- **Command** — the command line used to spawn the subprocess. Selecting a preset fills this in; editing it to match another preset re-detects that provider. API keys are *not* entered here — they live in the Secrets panel.

Check warning on line 81 in openhands/usage/agent-canvas/acp-agents.mdx

View check run for this annotation

Mintlify / Mintlify Validation (allhandsai) - vale-spellcheck

openhands/usage/agent-canvas/acp-agents.mdx#L81

Did you really mean 'subprocess'?
- **Model** — choose a suggested model for the provider or enter a custom model override. Built-in providers save a concrete model rather than leaving it blank.

Saving writes an `agent_settings_diff` (`agent_kind`, `acp_server`, `acp_command`, `acp_model`) to `PATCH /api/settings`. A running conversation keeps the agent it started with; the new choice applies to conversations you start afterward.

## Custom ACP servers
## Custom ACP Servers

Any stdio ACP server works: choose **Custom** in Settings → Agent and enter its launch command. Custom servers have no curated model list, so enter the model ID the server expects (if any) as a custom model. Pass credentials by adding the env vars the server reads as global secrets under **Settings → Secrets**.
Any stdio ACP server works: choose **Custom** in **Settings → Agent** and enter its launch command. Custom servers have no curated model list, so enter the model ID the server expects (if any) as a custom model. Pass credentials by adding the env vars the server reads as global secrets under **Settings → Secrets**.

## Related Guides

Expand Down
Loading