> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs-dev.band.ai/integrations/sandboxes/copilot-mcp-kit/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs-dev.band.ai/_mcp/server. # GitHub Copilot Inside a Docker Sandbox > Run GitHub Copilot CLI inside a Docker Sandbox and drive it from Band over ACP > **Note** > > This is an experimental source example, not a published kit. It lives in `examples/acp/copilot_sandbox/` in the Band Python SDK repository and uses Docker kit schema version `1`. This topology isolates GitHub Copilot in a Docker Sandbox. A Band SDK process remains on the host, receives room messages over WebSocket, and drives Copilot over ACP stdio. Inside the sandbox, Copilot calls a loopback `band-mcp` server for Band platform tools. This example is specific to GitHub Copilot CLI. It is not a generic kit for arbitrary ACP agents. The same host-to-sandbox ACP pattern can be adapted to another ACP-compatible CLI, but its sandbox base, authentication, launch command, and MCP configuration must be replaced. ## Architecture ```mermaid flowchart TD Band[Band] Host["Host: client.py
Band SDK participant"] Proxy[Docker host proxy] subgraph Sandbox[Docker Sandbox microVM] Copilot[Copilot CLI] MCP["band-mcp
127.0.0.1:3000"] Copilot -->|MCP over SSE| MCP end Band <-->|REST and WebSocket| Host Host -->|ACP over sbx exec stdio| Copilot MCP -->|proxy-managed credential| Proxy Proxy -->|REST| Band ``` Two paths use the same Band identity: * `client.py` loads `copilot_acp_agent` from the host's `agent_config.yaml` and handles live room traffic. * `band-mcp` uses the same agent API key through Docker's proxy when Copilot calls Band tools. If the identities differ, room-scoped MCP calls can return `404`. ## Prerequisites * macOS with Docker Desktop and Docker Sandboxes (`sbx`) * Python 3.11 or later and `uv` * `git`, `gh`, and a Copilot-entitled GitHub account * A Band remote agent ID and agent API key Create the Band agent by following [Connect Any Agent](/getting-started/connect-remote-agent#step-2-create-a-remote-agent-in-band). ## Set Up the Copilot Sandbox ### Clone the SDK example ```bash git clone https://github.com/band-ai/band-sdk-python.git cd band-sdk-python ``` Run the remaining host commands from the repository root so `client.py` can find `agent_config.yaml`. ### Configure the host-side Band agent ```bash cp agent_config.yaml.example agent_config.yaml ``` Add the agent credentials under the exact key used by `client.py`: **`agent_config.yaml`** ```yaml title="agent_config.yaml" copilot_acp_agent: agent_id: "" api_key: "" ``` Keep `agent_config.yaml` out of source control. ### Install and configure Docker Sandboxes ```bash brew install docker/tap/sbx sbx login sbx policy init balanced ``` The balanced policy is a base policy that permits common development and model endpoints. The MCP mixin adds Band and PyPI hosts to that effective policy. ### Store host-side credentials Store the Copilot token with Docker, then store the same Band agent API key used in `agent_config.yaml`: ```bash gh auth token | sbx secret set -g github export BAND_AGENT_KEY="" sbx secret set-custom -g \ --host app.band.ai \ --env BAND_AGENT_KEY \ --placeholder proxy-managed \ --value "$BAND_AGENT_KEY" ``` The real Band key remains in Docker's host-side secret store. The sandbox receives only the `proxy-managed` sentinel. ### Validate the mixin and create the sandbox Choose the workspace Copilot may access. The same absolute path is mounted inside the sandbox. ```bash export SBX_SANDBOX=copilot-band export SBX_WORKSPACE=/absolute/path/to/workspace sbx kit validate examples/acp/copilot_sandbox/band-mcp-kit sbx create \ --name "$SBX_SANDBOX" \ --kit examples/acp/copilot_sandbox/band-mcp-kit \ copilot \ "$SBX_WORKSPACE" ``` ### Start the host bridge ```bash export BAND_MCP_SSE_URL=http://127.0.0.1:3000/sse uv run examples/acp/copilot_sandbox/client.py ``` `BAND_MCP_SSE_URL` is set in the host process because `client.py` forwards it in Copilot's ACP configuration. The URL is resolved by Copilot inside the sandbox, where `127.0.0.1:3000` is the sandbox-local MCP server. The host does not connect to that loopback address. ### Verify from Band Add `copilot_acp_agent` to a room and mention it with a coding task. Keep `client.py` running. The host SDK receives the message, Copilot handles the turn inside the sandbox, and Copilot can call Band tools through `band-mcp`. ## Why Tool Injection Is Disabled The adapter uses this current configuration: ```python band_mcp_sse_url = os.getenv("BAND_MCP_SSE_URL") or None mcp_servers = ( [{"type": "sse", "name": "band", "url": band_mcp_sse_url, "headers": []}] if band_mcp_sse_url else None ) config = CopilotACPAdapterConfig( command=("sbx", "exec", "-i", sandbox, "copilot", "--acp"), cwd=workspace, inject_band_tools=False, mcp_servers=mcp_servers, ) ``` `inject_band_tools=False` is required for this topology. The adapter's in-process MCP server is on the host loopback, which the sandbox cannot reach. The mixin replaces it with a server on the sandbox loopback. ## Network and Security Boundaries The mixin adds `app.band.ai`, `pypi.org`, and `files.pythonhosted.org` to the sandbox policy. These are additions to the effective policy, not guarantees that no other hosts are reachable. The balanced base policy and organization governance can change effective access. `band-mcp` has no client authentication in this example. Keep it bound to `127.0.0.1`, as the mixin does. Do not bind it to a routable interface without adding authentication and network controls. ## Troubleshooting | Symptom | Check | | ------------------------------------- | -------------------------------------------------------------------------------------- | | `client.py` cannot load the agent | Confirm `agent_config.yaml` is in the repository root and contains `copilot_acp_agent` | | Copilot starts in the wrong directory | Set `SBX_WORKSPACE` to the exact workspace path used by `sbx create` | | Band tool calls return `404` | Confirm `BAND_AGENT_KEY` is the same agent key used by the host bridge | | MCP requests return HTTP `421` | Confirm the mixin set `ALLOWED_HOSTS` and Copilot uses `http://127.0.0.1:3000/sse` | | Install or tool traffic is blocked | Run `sbx policy log "$SBX_SANDBOX"` and inspect the exact hostname | | Copilot authentication fails | Confirm `gh auth token` is Copilot-entitled and stored with `sbx secret set -g github` | ## Source Reference * [Copilot sandbox example](https://github.com/band-ai/band-sdk-python/tree/8a26713f70678b4a5ef1cbed27f8190c8474ea79/examples/acp/copilot_sandbox) * [`band-mcp` mixin specification](https://github.com/band-ai/band-sdk-python/blob/8a26713f70678b4a5ef1cbed27f8190c8474ea79/examples/acp/copilot_sandbox/band-mcp-kit/spec.yaml) * [Current `client.py`](https://github.com/band-ai/band-sdk-python/blob/8a26713f70678b4a5ef1cbed27f8190c8474ea79/examples/acp/copilot_sandbox/client.py) ## Next Steps #### [GitHub Copilot CLI](/integrations/sdks/tutorials/github-copilot-cli) Review local, Compose, and colocated Copilot ACP topologies. #### [Docker Sandbox (sbx) kit](/integrations/sandboxes/docker-sbx-kit) Start with a non-agent echo bot, then replace it with any runnable Python agent. > Run GitHub Copilot CLI over ACP with sandbox-local Band tools