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

# MCP Server — ChatCLI as a server (and ACP)

> chatcli mcp-server exposes ChatCLI's FULL surface over MCP: chat with the complete experience pipeline (memory, contexts, skills, knowledge), the real agent/coder loops with per-call provider routing and quality toggles, every built-in tool, all skills as prompts, local state as chatcli:// resources, and cross-channel conversation continuity. chatcli acp exposes ChatCLI over the Agent Client Protocol with chat/agent/coder modes, live streaming and cancellation.

Beyond being an MCP **client** (consuming external tools — see [MCP Integration](/extensions/mcp-integration)), ChatCLI can also **be a server**: other agents/clients — Claude Code, Claude Desktop, IDEs, editors, even another ChatCLI — can drive ChatCLI over the protocol.

<Info>
  These are two external subcommands, both speaking JSON-RPC over **stdio** (stdin/stdout carry the protocol; all logging goes to the file logger):

  * **`chatcli mcp-server`** (alias `mcp-serve`) — an **MCP** (Model Context Protocol) server. Negotiates revision `2025-03-26` or `2024-11-05`.
  * **`chatcli acp`** — an **ACP** (Agent Client Protocol) server, for editors (Zed) and agent-to-agent use.
</Info>

***

## `chatcli mcp-server`

Exposes ChatCLI's **entire capability surface** — not a curated subset:

### Harness tools

| Tool | What it does |
| - | - |
| `ask_chatcli` | Chat with the **full ChatCLI experience pipeline** — the user's long-term memory and profile, `/context` attachments for the session, pinned and trigger-activated skills, knowledge retrieval and token-aware history compaction: the same enrichment an interactive turn gets. Keeps server-side history per `session`; accepts per-call `provider` / `model` overrides; `plain: true` skips the pipeline for a cheap raw turn. |
| `coder_task` | The **full agent loop** on a task — recommended for anything that needs autonomous work. Reads/edits files, runs commands and uses every built-in tool, memory, knowledge and any MCP server ChatCLI is itself connected to. The `session` id scopes which `/context` attachments and knowledge bases the run sees **and carries the run's own conversation**: agent/coder runs keep per-session history across calls, not a process-global one. Accepts `provider` / `model` and `quality` toggles. |
| `agent_task` | The **command-oriented (ReAct) loop** that proposes shell commands step by step. Prefer `coder_task` for general work. Same routing, quality and per-session conversation/scoping options. |
| `manage_session` | Persist and restore the conversations behind `ask_chatcli`'s `session` parameter — save/load/attach/detach/status/list/delete/clear/active, plus **full-text `search`** across the saved-session store, **`fork`** to copy a saved session, and **`policy_mode`** to switch the session's [security-policy mode](/coder/coder-security#session-policy-mode-policy) (`name: auto \| interactive \| status`). Shares the `/session` store with the interactive REPL; under `CHATCLI_HUB_ISOLATE=true` (multi-user gateway) `load`, `attach` and `delete` are refused on this surface because it carries no principal. `save` and `load` now **bind** the live session to the saved name, and `attach` binds even to a not-yet-existing one: every turn is written through to the file and writes made by other surfaces (REPL, gateway, another server) are adopted before each turn — [cross-surface continuity](/context/session-management#cross-surface-continuity); `detach` drops the binding, `status` reports it. Live sessions also **autosave by default** as rolling `mcp-<name>` mirrors after every turn (`CHATCLI_MCP_SESSION_AUTOSAVE`; unset follows `CHATCLI_SESSION_AUTOSAVE`), and `clear` saves one last time before discarding. |
| `list_providers` | The routing surface: configured providers, active provider/model, and each provider's cataloged models. |

The `quality` parameter maps to the `CHATCLI_QUALITY_*` namespace, so a caller can turn on **plan, refine, verify, reflexion, convergence and lessons** for a single run:

```json theme={"system"}
{ "name": "agent_task", "arguments": {
    "task": "audit the auth flow",
    "provider": "DEVIN", "model": "gpt-5.6-sol",
    "quality": { "CHATCLI_QUALITY_ENABLED": "true" }
} }
```

### Every plugin tool

All registered built-in and external plugins are advertised individually (37 on a default build): files (`read`, `search`, `tree`, `coder`), web (`websearch`, `webfetch`, `http`, `api-explorer`), memory (`memory`, `recall`), knowledge (`knowledge`, `context`, `compress`, `docs-flatten`), visuals (`diagram`, `graphview`, `image`), plus `moa`, `lsp`, `scheduler`, `session`, `osv`, `wikipedia`, `registry-tags`, `todo`, `tools`, `channels`, `send`, `proc`, `skill`, `speak`…

* Each tool carries its **usage** embedded in the description and a **`readOnlyHint` annotation** derived from ChatCLI's per-plugin capability metadata.
* Arguments follow the same contract the agent uses: a JSON envelope (`{"cmd":"read","args":{...}}`) or a flat string.
* Interactive tools that require a live terminal (`ask`, `voice`, `park`) are never exposed — over stdio they would hang forever.

### Exposure policy — `CHATCLI_MCP_TOOLS`

| Value | Behavior |
| - | - |
| `all` *(default)* | Every tool, including write/exec — starting the server is the opt-in. |
| `safe` | Only tools whose capability metadata reports **read-only**. |
| `read,search,recall` | Explicit allowlist (comma-separated, with or without `@`). |

### Skills as MCP prompts

Every installed skill is served through `prompts/list` / `prompts/get` — the client can pull ChatCLI's whole skill catalog as ready-to-use prompts. [Slash-command templates](/extensions/slash-commands) join the same listing, carrying the MCP-spec `arguments` field (an `args` argument built from the command's `argument-hint`; skills with an `argument-hint` carry it too): `prompts/get` with `{"name":"review-pr","arguments":{"args":"1326 security"}}` returns the fully expanded template, with pre-execution lines resolved through the security policy.

### Local state as MCP resources — `chatcli://`

Everything the user built in ChatCLI is browsable read-only through `resources/list` / `resources/read`:

| URI | Content |
| - | - |
| `chatcli://memory/index` · `longterm` · `profile` · `projects` · `stats` | The user's long-term memory, profile and tracked projects |
| `chatcli://contexts` · `chatcli://contexts/{name}` | The `/context` store catalog and each context's rendered content |
| `chatcli://knowledge/{kb}` · `chatcli://knowledge/{kb}/{source}?offset=N` | Knowledge-base TOC and paged document reads |
| `chatcli://skills` · `chatcli://skills/{name}` | Skill catalog **with triggers** (so a client can reproduce activation semantics) and each skill's body |
| `chatcli://sessions` · `chatcli://sessions/{name}` | Saved-session names and their JSON content |

Mutations go through the tools surface (`memory`, `context`, `manage_session`, …). `CHATCLI_MCP_RESOURCES=off` disables the resources surface entirely.

### Cross-channel continuity — the conversation hub

The server joins the [conversation hub](/gateway/conversation-hub) in **resume mode**: it adopts the principal's active conversation instead of rotating it, so a thread started in the interactive REPL or on a gateway channel (Telegram, Slack…) continues seamlessly from any MCP client — and the turns made over MCP show up back in the REPL. `CHATCLI_MCP_HUB=off` opts out; `CHATCLI_MCP_HUB_PRINCIPAL` isolates the MCP thread under its own principal.

### Unattended safety — `CHATCLI_MCP_DANGER`

stdin carries the protocol, so the server runs **unattended** (every interactive confirmation auto-approves, like the gateway daemon). Dangerous commands in `coder_task` exec calls are always hard-blocked regardless of policy; for the remaining shell-command gate, `CHATCLI_MCP_DANGER=block` declines dangerous commands **in-band** (the model sees the refusal and replans) instead of auto-approving. Default is `allow`, matching the gateway.

### Approval prompts via elicitation

Clients that declare the **`elicitation` capability** at `initialize` get a better contract: coder-policy **`ask` rules** and dangerous `coder_task` exec commands raise an `elicitation/create` approval form in the client instead of the blanket behavior above. When the action has a persistable policy pattern, the form offers the **full terminal vocabulary** as a `decision` enum — `allow_once`, `allow_always`, `deny_once`, `deny_always` — and the *always* choices persist a rule in `coder_policy.json`, exactly like the terminal prompt (`exec` commands never get the *always* choices, by design). Dangerous exec commands keep the simple `approve` boolean form. Anything except an explicit *accept* with an allow decision denies — decline, cancel or a transport failure — and the model replans in-band. Clients without the capability (most wrapped CLIs) keep the exact contract of the previous section; no server→client request is ever sent to them.

Some clients declare the capability but never actually render the form — the run would otherwise sit frozen waiting for an answer until the client killed the call. Each approval round-trip is therefore bounded by **`CHATCLI_MCP_PERMISSION_TIMEOUT`** (a Go duration like `90s`/`10m` or plain seconds; default `600s`; `0`/`off` lifts the bound to a 24h ceiling — never truly unbounded; the same variable bounds [ACP permission dialogs](/server/acp)). MCP clients that enforce their own shorter `tools/call` timeout kill the whole call first — tune the variable below your client's limit to keep the run alive. An unanswered form **denies fail-safe** — never auto-approves, since the form may be visible with the user about to say no — and the model is told the request got **no response** (not a user denial), so it continues without the action and can explain what happened. After the first timeout, later prompts in the same run fail fast instead of stalling again. If your client persistently declares elicitation without showing dialogs, set **`CHATCLI_MCP_ELICITATION=off`** to disable the bridge entirely and restore the unattended contract of the previous section.

To skip the forms entirely for a session, the `manage_session` tool's **`policy_mode` action** (`name: auto`) switches the session into [policy automode](/coder/coder-security#session-policy-mode-policy): `ask` rules auto-approve while deny rules and safety-immune operations keep gating; `name: interactive` restores the forms.

### No provider configured? Still useful

An MCP client brings its **own model** — ChatCLI's direct tools don't need a local LLM. Without any key/OAuth in ChatCLI, the LLM-backed tools (`ask_chatcli`, `agent_task`, `coder_task`) are simply **hidden from `tools/list`**, and every direct tool keeps working (persistent memory, knowledge bases, LSP, diagrams, scheduler… driven by the caller's model). Configure a provider and restart to enable the harness tools.

### The environment an MCP client passes on

An MCP client spawns the server as a child process **without your shell profile**: `CHATCLI_DOTENV` and everything you export from `.zshrc`/`.bashrc` never reach it, and its working directory is whatever the client chose. ChatCLI therefore discovers its environment file as `$CHATCLI_DOTENV` → `./.env` → `~/.chatcli/.env` → `~/.env`, first match wins — keep yours in one of the home locations and the server sees exactly what your terminal sees. Anything the client must pin explicitly goes in its `env` block.

This is the usual explanation for two symptoms: providers that work in the terminal being absent from `tools/list`, and Bedrock answering from the wrong AWS account (without `AWS_PROFILE`/`BEDROCK_PROFILE` the SDK falls back to the `default` profile, and the credential chain then fails with the misleading *no EC2 IMDS role found*). The boot log records which file loaded, and credential errors name the profile, the environment file in effect and the `aws sso login` command to refresh the session.

### Connecting from Claude Code

```bash theme={"system"}
claude mcp add chatcli -- chatcli mcp-server
```

Or in a JSON config:

```json theme={"system"}
{
  "mcpServers": {
    "chatcli": {
      "command": "chatcli",
      "args": ["mcp-server"],
      "env": { "LLM_PROVIDER": "CLAUDEAI", "LLM_MODEL": "claude-sonnet-4-6" }
    }
  }
}
```

<Note>
  The agent and coder render to stdout; the backend captures that output during the run and returns it as the tool result. Direct tool calls are stdout-captured too, so a chatty plugin can never corrupt the protocol channel. Long-running calls don't block the read loop — requests dispatch concurrently, which is what makes cancellation work.
</Note>

***

## `chatcli acp`

A full **Agent Client Protocol** server: sessions with chat/agent/coder modes, structured tool calls and plan updates, slash commands and native IDE permission dialogs — the way to run ChatCLI **inside JetBrains IDEs and Zed**.

```bash theme={"system"}
chatcli acp
```

* **Structured updates** — agent/coder runs emit native `tool_call`/`tool_call_update`, `agent_thought_chunk` and `plan` frames; the IDE renders collapsible tool calls and a live plan instead of a streamed transcript.
* **Slash commands** — `/coder`, `/config`, `/model` and a headless allowlist are advertised to the client and work from the IDE prompt box.
* **Permission dialogs** — dangerous commands and security-policy `ask` rules raise `session/request_permission` (the IDE's native dialog with allow/reject, once/always) instead of blanket auto-approve/block.
* **Cancellation** — `session/cancel` interrupts an in-flight prompt and closes any open tool call.
* **Session restore** — `session/load` (capability `loadSession: true`) brings a prior session id back to life (live state, or its `mcp-<id>` autosave mirror after a restart) and replays the conversation into the client; `/session` from the prompt box operates per session and binds to named sessions for [cross-surface continuity](/context/session-management#cross-surface-continuity).

Full setup (JetBrains `~/.jetbrains/acp.json`, Zed `agent_servers`), the command surface, security model and protocol details live on the dedicated page: **[ACP — ChatCLI inside your IDE](/server/acp)**.

***

## See also

* [ACP — ChatCLI inside your IDE](/server/acp) — the ACP server in depth: IDE setup, slash commands, permission dialogs
* [MCP Integration](/extensions/mcp-integration) — ChatCLI as an MCP **client**, including `chatcli mcp add`
* [Environment Variables](/reference/environment-variables) — `LLM_PROVIDER`, `LLM_MODEL`, `CHATCLI_MCP_TOOLS`
* [Command Reference](/reference/command-reference) — external subcommands


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.