> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ACP — ChatCLI inside your IDE

> chatcli acp turns ChatCLI into a native IDE agent over the Agent Client Protocol: JetBrains IDEs and Zed drive the real chat/agent/coder engines with structured tool calls, live plan tracking, slash commands and native permission dialogs — no terminal emulation, no scraped output.

The **Agent Client Protocol (ACP)** is an open protocol that lets editors and IDEs host external coding agents as first-class citizens: the IDE renders the agent's reasoning, tool calls, plans and permission prompts natively, while the agent runs as a separate process speaking JSON-RPC over stdio.

`chatcli acp` is ChatCLI's ACP server. Everything you have configured in ChatCLI — providers, models, memory, contexts, skills, plugins, MCP servers — drives your IDE's AI chat.

<Info>
  What the IDE renders for agent/coder runs is fully **structured** — not a streamed terminal transcript:

  * **Thoughts** — the agent's reasoning arrives as native thought chunks (collapsible in most clients).
  * **Tool calls** — each action is a first-class tool call with a human title ("Reading: main.go"), a semantic kind (read, edit, execute, search…), live status, and the files it touches. Successful file reads show *which* file was read — never a dump of its contents into the chat.
  * **Plan** — the coder's task list streams as a live plan panel, checked off as the agent progresses.
  * **Final answer** — clean assistant prose, rendered as markdown by the IDE.
  * **Permission dialogs** — dangerous commands pause the run and raise the IDE's native Allow/Reject dialog.
</Info>

## Quick start

```bash theme={"system"}
# 1. Make sure chatcli works standalone first
chatcli --version

# 2. Start the ACP server (your IDE does this for you once configured)
chatcli acp
```

The process speaks newline-delimited JSON-RPC on stdin/stdout. All logging goes to the file logger — the protocol channel stays clean.

## JetBrains IDEs (IntelliJ IDEA, GoLand, WebStorm, …)

JetBrains AI Assistant hosts custom ACP agents natively (macOS and Linux; no AI subscription required for ACP agents).

<Steps>
  <Step title="Open the custom-agent configuration">
    In the **AI Chat** tool window, open the agent dropdown and choose **Add Custom Agent**. The IDE creates and opens `~/.jetbrains/acp.json`.
  </Step>

  <Step title="Register ChatCLI">
    ```json ~/.jetbrains/acp.json theme={"system"}
    {
      "default_mcp_settings": {
        "use_custom_mcp": true,
        "use_idea_mcp": false
      },
      "agent_servers": {
        "ChatCLI": {
          "command": "/usr/local/bin/chatcli",
          "args": ["acp"],
          "env": {
            "LLM_PROVIDER": "CLAUDEAI",
            "LLM_MODEL": "claude-sonnet-4-6"
          }
        }
      }
    }
    ```

    * `command` must be an **absolute path** (`which chatcli` to find it).
    * `env` is optional — with it you pin provider/model for the IDE independently of your terminal sessions; without it, ChatCLI boots with your regular `.env`/environment resolution.
  </Step>

  <Step title="Select ChatCLI and chat">
    Back in AI Chat, pick **ChatCLI** from the agent dropdown and send a prompt. Custom agents show a distinct icon.
  </Step>
</Steps>

<Note>
  `use_custom_mcp` / `use_idea_mcp` control which MCP servers the **IDE** offers to agents. ChatCLI brings its own MCP client configuration (`~/.chatcli/mcp_servers.json`) either way — tools you configured in ChatCLI keep working inside the IDE.
</Note>

## Zed

Add ChatCLI under `agent_servers` in Zed's `settings.json`:

```json theme={"system"}
{
  "agent_servers": {
    "ChatCLI": {
      "command": "/usr/local/bin/chatcli",
      "args": ["acp"],
      "env": { "LLM_PROVIDER": "CLAUDEAI" }
    }
  }
}
```

Then open the Agent Panel and select **ChatCLI**.

## Session modes

Every ACP session runs in one of three modes, advertised to the client on `session/new` and switchable at any time:

| Mode    | What it is                                                                                 | Default |
| ------- | ------------------------------------------------------------------------------------------ | ------- |
| `chat`  | Direct model conversation — no tools, full experience pipeline (memory, contexts, skills). |         |
| `agent` | The full autonomous ReAct loop with every ChatCLI tool.                                    | ✓       |
| `coder` | The coding-focused loop: read/edit files, run commands, iterate — with live plan tracking. |         |

Switch modes from the IDE's mode picker, or simply type the command in the prompt:

```
/coder            → switch this session to coder mode
/coder fix the failing tests   → switch AND run the task immediately
/chat             → back to plain conversation
```

Mode changes are confirmed to the client via `current_mode_update`, so the IDE picker always reflects reality.

## Slash commands in the IDE

Type `/` in the prompt box: the IDE autocompletes ChatCLI's command surface (advertised via `available_commands_update`). Three groups:

**Mode switches** — `/chat`, `/agent`, `/coder` (and `/run` as an alias for agent).

**Headless-capable commands** — run for real, output returned to the chat:

| Category         | Commands                                                                                                   |
| ---------------- | ---------------------------------------------------------------------------------------------------------- |
| Model & provider | `/switch <provider> [--model <m>]`, `/provider`, `/model`, `/max-tokens`                                   |
| Configuration    | `/config` (panorama and every section: `/config providers`, `/config agent`, `/config ui theme <name>`, …) |
| Session          | `/session`, `/newsession`, `/compact`, `/export`                                                           |
| Context & memory | `/context`, `/memory`                                                                                      |
| Quality pipeline | `/thinking`, `/refine`, `/verify`, `/reflect`, `/moa`                                                      |
| Integrations     | `/mcp`, `/websearch`, `/skill`, `/plugin`                                                                  |
| Diagnostics      | `/cost`, `/metrics`, `/ratelimit`, `/version`, `/help`                                                     |

**Everything else** — commands that need a live terminal (`/menu`, `/gateway`, `/schedule`, `/auth`, …) answer with a clear "not available over the IDE connection" message instead of failing silently.

<Note>
  A prompt that merely *starts* with a slash — a filesystem path like `/usr/local/bin explain this`, a typo'd word — is **not** hijacked: unknown tokens flow to the model as normal user text.
</Note>

<Warning>
  Commands that would ask for confirmation on a terminal (e.g. `/context rm <name>`) run with stdin quarantined on the server: any confirmation is answered as **deny, fail-safe**. Destructive maintenance is best done in the terminal REPL.
</Warning>

## Permission dialogs

Unattended agent servers historically face a hard choice: auto-approve everything or block everything. ACP has a better answer — `session/request_permission` — and ChatCLI uses it:

* When the coder wants to run a command classified **dangerous** (recursive deletes, force pushes, privilege escalation…), the run pauses and your IDE shows its native approval dialog with **Allow once** / **Reject once**.
* Anything except an explicit *Allow* — reject, dialog dismissed, client crash, timeout — **denies** the command. The agent sees the refusal in-band and replans.
* The same gate covers shell blocks the agent proposes in agent mode.

Clients that don't implement the permission request (or headless drivers like MCP `agent_task`) get the strict behavior: dangerous commands are refused.

## Your MCP servers work here too

The ACP process is a full ChatCLI boot — including the **MCP client**. If `~/.chatcli/mcp_servers.json` exists, every configured MCP server is connected at startup and its tools join the agent's toolbox, exactly like in the terminal:

* Ask the agent something that needs an MCP tool ("check the open Jira issues", "query the staging database") and it calls the connected server's tool autonomously. In the IDE, the call renders as a **native structured tool call** like any built-in.
* **Hot reload** — editing `mcp_servers.json` reconnects servers live; no IDE or agent restart needed. `/mcp` from the prompt box shows connection status and tools.
* Remote servers using OAuth must be authorized beforehand (run `@mcp-login` in the terminal once; tokens persist in the keychain).

<Note>
  Connections are established asynchronously at boot: a prompt sent in the very first seconds may not see a slow server's tools yet — they join the catalog as soon as the connection completes.

  One conceptual difference from `chatcli mcp-server`: ACP has no client-facing tool list, so the IDE never invokes MCP tools directly — the **agent** uses them on your behalf. Direct tool invocation (hub passthrough) is an MCP-server feature.
</Note>

## Under the hood (for integrators)

ChatCLI implements ACP **protocol version 1**. Methods:

| Method             | Notes                                                                                                                                                      |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `initialize`       | Returns `agentInfo {name: "chatcli", version}`, capabilities (`embeddedContext: true`), no auth required.                                                  |
| `session/new`      | Returns `sessionId` + `modes`; `available_commands_update` follows immediately after the response.                                                         |
| `session/set_mode` | Validates the mode, confirms via `current_mode_update`.                                                                                                    |
| `session/prompt`   | Accepts `text`, `resource_link` and embedded `resource` content blocks. One prompt at a time per session — an overlapping prompt is rejected, not queued.  |
| `session/cancel`   | Interrupts the in-flight prompt (`stopReason: "cancelled"`); any announced-but-unfinished tool call is closed as `failed`, so no spinner is ever orphaned. |

`session/update` kinds emitted: `agent_thought_chunk`, `agent_message_chunk`, `tool_call`, `tool_call_update`, `plan`, `current_mode_update`, `available_commands_update`. Tool calls carry `kind` (`read`/`edit`/`delete`/`move`/`search`/`execute`/`think`/`fetch`/`other`), `status`, `rawInput`, `locations` (file paths for follow-along), and content capped for display — the model always receives the full output; the chat view gets a bounded summary.

File mentions from the IDE work both ways: `resource_link` blocks arrive as file references the agent's tools open themselves, and `resource` blocks (embedded contents) are injected as attached context.

## Operational notes

* **One run at a time** — agent/coder runs serialize process-wide (they share the engine state). A second session's prompt waits for the current run to finish; a second prompt on the *same* session is rejected while one is in flight.
* **Environment** — the ACP process is a normal ChatCLI boot: `.env`, keychain-backed OAuth logins, provider catalogs, MCP client config and skills all resolve exactly as in your terminal.
* **Sessions are in-process** — IDE sessions map to ChatCLI's process history. `/newsession` and `/compact` act on it; `session/load` is not implemented yet.
* **Logs** — stdout is the protocol; diagnostics go to the standard ChatCLI log file. Set `LOG_LEVEL=debug` in the agent's `env` block when investigating.

## Troubleshooting

| Symptom                                                   | Fix                                                                                                                                                                             |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Agent doesn't appear in the IDE dropdown                  | Validate `~/.jetbrains/acp.json` syntax; restart the IDE.                                                                                                                       |
| Agent fails to start                                      | Use the **absolute** binary path in `command`; test `chatcli acp` in a terminal — type `{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}` and expect a JSON response. |
| Empty replies in chat mode                                | Provider/model not resolvable in the ACP process environment — set `LLM_PROVIDER`/`LLM_MODEL` (or API keys) in the `env` block.                                                 |
| A command answers "not available over the IDE connection" | It needs a live terminal — run it in the REPL. The `/` autocomplete lists everything that works headless.                                                                       |
| Dangerous command silently refused                        | Your client doesn't implement `session/request_permission`; ChatCLI fails safe. Run it from the terminal, or approve via the dialog in a client that supports it.               |

## See also

* [MCP Server](/features/mcp-server) — the sibling subcommand: ChatCLI's full surface as MCP tools
* [Coder Plugin](/features/coder-plugin) — what the coder engine can do
* [Coder Security](/features/coder-security) — the dangerous-command classification behind permission dialogs
* [Command Reference](/reference/command-reference) — the full slash-command surface
* [Environment Variables](/reference/environment-variables) — provider/model/security knobs
