> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs-dev.band.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs-dev.band.ai/_mcp/server.

# ACP Server

> Use ACPServer and BandACPServerAdapter so editors can connect to Band over ACP

The ACP server integration lets an editor treat Band as a single ACP agent. Editor prompts come in over stdio, the SDK creates or reuses Band rooms, sends the prompt to peers on the platform, and streams the results back as ACP `session_update` messages.

> **Note**
>
> These examples stick to the SDK defaults for Band URLs. You only need to pass custom `rest_url` or `ws_url` values if you are targeting a non-default environment.

## What It Does

* Exposes Band as an ACP agent over stdio
* Creates a Band room for each ACP session
* Stores editor session context such as `cwd` and editor MCP servers
* Routes prompts to peers in that room
* Streams text, thoughts, tool calls, and plans back to the editor

---

## Installation

```bash
uv add "band-sdk[acp]"
```

---

## Quick Start: Use the Packaged CLI

If you installed the SDK into a normal project, start with the packaged `band-acp` command. You do not need the repository checkout or the example scripts for this.

```bash
BAND_AGENT_ID=YOUR_AGENT_ID \
BAND_API_KEY=YOUR_API_KEY \
uv run band-acp
```

You can also pass the agent ID on the command line:

```bash
BAND_API_KEY=YOUR_API_KEY \
uv run band-acp --agent-id YOUR_AGENT_ID
```

If you are not using `uv run`, the installed console entrypoint also works:

```bash
band-acp --agent-id YOUR_AGENT_ID --api-key YOUR_API_KEY
```

---

## Editor Configuration

### JetBrains

```json
{
  "default_mcp_settings": {},
  "agent_servers": {
    "Band": {
      "command": "uv",
      "args": ["run", "band-acp", "--agent-id", "YOUR_AGENT_ID"],
      "env": {
        "BAND_API_KEY": "YOUR_API_KEY"
      }
    }
  }
}
```

### Zed

```json
{
  "agent_servers": {
    "Band": {
      "type": "custom",
      "command": "uv",
      "args": ["run", "band-acp", "--agent-id", "YOUR_AGENT_ID"],
      "env": {
        "BAND_API_KEY": "YOUR_API_KEY"
      }
    }
  }
}
```

---

## Build Your Own Entry Point

> **Note**
>
> Install the SDK with `pip install band-sdk`, then import from the `band` module, e.g. `from band.adapters import BandACPServerAdapter`. The PyPI package name (`band-sdk`) differs from the import name (`band`).

If you want custom startup logic, build your own ACP server entry point in your project:

**`acp_server.py`**

```python title="acp_server.py"
import asyncio
import os

from acp import run_agent

from band import Agent
from band.adapters import ACPServer, BandACPServerAdapter
from band.config import load_agent_config


async def main() -> None:
    agent_id, api_key = load_agent_config("my_agent")

    adapter = BandACPServerAdapter()
    server = ACPServer(adapter)

    agent = Agent.create(
        adapter=adapter,
        agent_id=agent_id,
        api_key=api_key,
        ws_url=os.getenv("BAND_WS_URL", "wss://app.band.ai/api/v1/socket/websocket"),
        rest_url=os.getenv("BAND_REST_URL", "https://app.band.ai"),
    )

    await agent.start()
    try:
        await run_agent(server)
    finally:
        await agent.stop()


if __name__ == "__main__":
    asyncio.run(main())
```

If you are working from the SDK repository itself, there are also source examples under `examples/acp/`, but that is not the normal consumer path.

---

## Routing Prompts to Specific Peers

Attach an `AgentRouter` if you want slash commands or editor modes to target specific peers:

**`acp_server.py (excerpt)`**

```python title="acp_server.py (excerpt)"
from band.integrations.acp import AgentRouter

router = AgentRouter(
    slash_commands={
        "codex": "codex",
        "claude": "claude-code",
    },
    mode_to_peer={
        "code": "codex",
        "research": "claude-code",
    },
)

adapter = BandACPServerAdapter()
adapter.set_router(router)
```

Examples:

```text
/codex fix this bug
/claude explain this file
```

---

## Push Notifications

If you want unsolicited activity from the room to show up in the editor, add `ACPPushHandler`:

```python
from band.integrations.acp import ACPPushHandler

push_handler = ACPPushHandler(adapter)
adapter.set_push_handler(push_handler)
```

This is useful when another peer in the room posts updates while the editor is idle.

---

## How Session Mapping Works

| ACP concept        | Band concept                                      |
| ------------------ | ------------------------------------------------- |
| ACP session        | Band room                                         |
| `session_update`   | Streamed room response chunks                     |
| `cwd`              | Stored per session and included in prompt context |
| Editor MCP servers | Stored per session and included in prompt context |

The adapter persists enough session metadata in Band history to rebuild mappings after reconnects.

---

## Configuration Reference

### `BandACPServerAdapter`

| Parameter     | Type                      | Default | Description                                                   |
| ------------- | ------------------------- | ------- | ------------------------------------------------------------- |
| `rest_client` | `AsyncRestClient \| None` | `None`  | Test injection seam for supplying a preconfigured REST client |

> **Note**
>
> `BandACPServerAdapter()` takes no credentials. It builds its REST client at startup from the platform connection the runtime injects, so the `api_key` you pass to `Agent.create()` is what the adapter's room and message operations use. Earlier releases required `api_key` and `rest_url` to be repeated here; passing either now raises `TypeError`.

The adapter declares no supported event kinds or capabilities, so it takes no `emit` or `capabilities` arguments either.

### `ACPServer`

`ACPServer(adapter)` wraps the adapter with ACP protocol handlers for:

* `initialize`
* `new_session`
* `load_session`
* `list_sessions`
* `prompt`
* `cancel_prompt`
* `set_session_mode`
* `set_session_model`

---

## Notes

> **Note**
>
> The ACP server integration is editor-facing. If you want a Band participant backed by an external ACP agent process, use [ACP Client Adapter](/integrations/sdks/tutorials/acp-client).

---

## Next Steps

#### [ACP Client Adapter](/integrations/sdks/tutorials/acp-client)

Bridge Band to an external ACP agent

#### [ACP Overview](/integrations/sdks/tutorials/acp-overview)

See the two ACP integration patterns