Skip to content

Commit 0ee038d

Browse files
hubwriterCopilot
andauthored
Copilot CLI: Revise ACP server article and add details of slash command support (#62189)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 1b655e7 commit 0ee038d

2 files changed

Lines changed: 124 additions & 12 deletions

File tree

content/copilot/reference/copilot-cli-reference/acp-server.md

Lines changed: 122 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,35 +30,75 @@ The Agent Client Protocol (ACP) is a protocol that standardizes communication be
3030

3131
## Starting the ACP server
3232

33-
{% data variables.copilot.copilot_cli %} can be started as an ACP server using the `--acp` flag. The server supports two modes, `stdio` and `TCP`.
33+
Use the `--acp` option of the `copilot` command to start the CLI's ACP server. You can specify the transport mode with either the `--stdio` or `--port` options. If no transport mode is specified, the server defaults to stdio mode.
3434

35-
> [!NOTE]
36-
> When running in ACP mode, the tool-filtering flags (`--available-tools`, `--excluded-tools`) and the reasoning flag (`--effort`, `--reasoning-effort`) are applied to each session started by the ACP client.
35+
### Options applied to every session
36+
37+
The ACP `session/new` request only lets a client set a few session parameters, such as the working directory and the MCP servers to use. It does not carry tool-filtering or reasoning settings. To configure those, pass the corresponding options when you **start the server**. The server stores the values and applies them as the initial configuration for every session it creates or loads, for any client that connects. A connecting client does not choose these values—whoever launches the server does.
3738

38-
### stdio mode (recommended for IDE integration)
39+
| Server option | Accepted value | Effect on every session |
40+
|---------------|----------------|-------------------------|
41+
| `--available-tools=TOOL ...` | A quoted, comma-separated list of tool names | The session can use only the listed tools. |
42+
| `--excluded-tools=TOOL ...` | A quoted, comma-separated list of tool names | The listed tools are removed from the session. |
43+
| `--effort=LEVEL`, `--reasoning-effort=LEVEL` | `low`, `medium`, `high`, `xhigh`, or `max` | Sets the session's initial reasoning effort. |
3944

40-
By default, when providing the `--acp` flag, `stdio` mode will be inferred. The `--stdio` flag can also be provided for disambiguation.
45+
For example, this command starts a server whose sessions all use maximum reasoning effort and expose only the `bash` and `view` tools:
46+
47+
```bash
48+
copilot --acp --port 3000 --effort=max --available-tools="bash,view"
49+
```
50+
51+
Every session the connected client opens against that server inherits those settings. Because the values are fixed when the server starts, a client cannot change them per session through `session/new`.
52+
53+
### stdio mode
54+
55+
stdio mode is inferred by default when you start the ACP server. You can also use the `--stdio` option for disambiguation.
4156

4257
```bash
4358
copilot --acp --stdio
4459
```
4560

4661
### TCP mode
4762

48-
If the `--port` flag is provided in combination with the `--acp` flag, the server is started in TCP mode.
63+
If the `--port` option is provided in combination with the `--acp` option, the server is started in TCP mode.
4964

5065
```bash
5166
copilot --acp --port 3000
5267
```
5368

54-
## Integrating with the ACP server
69+
### Choosing between stdio and TCP
70+
71+
Both transport modes carry the same ACP messages, encoded as newline-delimited JSON (NDJSON). They differ only in how a client connects to the server and how the server's lifecycle is managed. The two modes are mutually exclusive: passing both `--stdio` and `--port` is rejected.
72+
73+
| Aspect | stdio mode | TCP mode |
74+
|---|---|---|
75+
| **How the client connects** | The client launches `copilot --acp` as a child process and exchanges messages over the process's standard input and output. | The server opens a TCP listener that clients connect to over a network socket. By default it binds to the loopback address `127.0.0.1`. |
76+
| **Number of clients** | A single client—the process that spawned the server and owns the pipe. | The listener accepts socket connections, each handled as its own agent connection. |
77+
| **Lifecycle** | Tied to the parent process. When the input stream closes—because the parent exits or closes the pipe—the server shuts down automatically. | Independent of any single client. The server keeps listening on the port until it is stopped, for example with <kbd>Ctrl</kbd>+<kbd>C</kbd>. |
78+
| **Standard output** | Reserved for the NDJSON protocol stream, so it can't be used for logs or other text. | Free for other use, because protocol traffic travels over the socket. |
79+
80+
When to use each mode:
5581

56-
There is a growing ecosystem of libraries to programmatically interact with ACP servers. Given {% data variables.copilot.copilot_cli %} is correctly installed and authenticated, the following example demonstrates using the [typescript](https://agentclientprotocol.com/libraries/typescript) client to send a single prompt and print the AI response.
82+
* Use **stdio mode** when an editor, IDE, or script spawns {% data variables.copilot.copilot_cli_short %} directly as a subprocess. This is the default and the recommended setup for IDE integration, because the transport is established automatically when the process starts and torn down when it exits.
83+
* Use **TCP mode** when a client needs to reach the server over a socket instead of a pipe—for example, from a separate process or container, or when connecting to a longer-lived server on a known port.
5784

58-
```typescript
85+
## Example: integrating with the ACP server
86+
87+
The following example is a client application that uses {% data variables.product.prodname_copilot_short %} by interacting with {% data variables.copilot.copilot_cli %}'s ACP server. It starts the ACP server in stdio mode, opens a session, asks you to enter a prompt, sends it, and prints the streamed response.
88+
89+
There is a growing ecosystem of libraries for interacting with ACP servers programmatically. This example uses the [ACP TypeScript library](https://agentclientprotocol.com/libraries/typescript).
90+
91+
To run this example, you need the following dependencies:
92+
93+
* [Node.js](https://nodejs.org) version 18 or later.
94+
* {% data variables.copilot.copilot_cli %}, installed and authenticated.
95+
* The `@agentclientprotocol/sdk` package, which provides the ACP TypeScript library. Install it by running `npm install @agentclientprotocol/sdk`.
96+
97+
```typescript copy
5998
import * as acp from "@agentclientprotocol/sdk";
6099
import { spawn } from "node:child_process";
61100
import { Readable, Writable } from "node:stream";
101+
import * as readline from "node:readline/promises";
62102

63103
async function main() {
64104
const executable = process.env.COPILOT_CLI_PATH ?? "copilot";
@@ -105,8 +145,14 @@ async function main() {
105145
});
106146

107147
process.stdout.write("Session started!\n");
108-
const promptText = "Hello ACP Server!";
109-
process.stdout.write(`Sending prompt: '${promptText}'\n`);
148+
149+
// Ask the user to enter a prompt instead of using a hard-coded one.
150+
const rl = readline.createInterface({
151+
input: process.stdin,
152+
output: process.stdout,
153+
});
154+
const promptText = await rl.question("Enter a prompt: ");
155+
rl.close();
110156

111157
const promptResult = await connection.prompt({
112158
sessionId: sessionResult.sessionId,
@@ -134,7 +180,71 @@ main().catch((error) => {
134180
});
135181
```
136182

183+
To run the example:
184+
185+
1. Save the code above to a file named `acp-client.ts`.
186+
1. Run the file with `npx tsx`, which runs the TypeScript directly without a separate build step:
187+
188+
```bash
189+
npx tsx acp-client.ts
190+
```
191+
192+
## Using slash commands
193+
194+
{% data variables.copilot.copilot_cli %}'s built-in slash commands can be run over ACP. To invoke one, send it as an ordinary prompt whose text is the command, passed as a single text content block—for example, `/context` or `/session info`. The server recognizes the command and runs it directly: informational commands such as `/usage` or `/context` return their output without invoking the model, while action commands such as `/plan` or `/review` start the corresponding agent task. Either way, the command text is not sent to the model as a question.
195+
196+
### Discovering available commands
197+
198+
The server advertises the commands it supports through the standard ACP `available_commands_update` session notification. It is sent after a session is created or loaded, and again whenever the set changes—for example, when skills finish loading. This advertised list is the authoritative, always-current set of commands you can run over ACP, and clients typically surface it in a command menu.
199+
200+
The advertised list contains:
201+
202+
* **Built-in commands**, such as `/compact`, `/context`, `/usage`, `/env`, `/model`, `/mcp`, `/plan`, `/review`, `/research`, `/session`, and `/rename`.
203+
* **Enabled, user-invocable skills**, which appear as `/SKILL-NAME` commands.
204+
205+
Commands that the client itself registers are not advertised back to it.
206+
207+
### Accessing the list from your client
208+
209+
Because the list arrives as a notification rather than in response to a request, there is no method to fetch it on demand. Your client accesses it by handling the `session/update` notification and reacting to updates whose type is `available_commands_update`. Each entry has a `name` (without the leading slash), a `description`, and an optional `input.hint` that describes the command's arguments. The notification is re-sent whenever the set changes, so treat each one as a complete replacement of any list you have cached.
210+
211+
The following `sessionUpdate` handler captures the advertised commands, extending the `client` object from the example shown earlier.
212+
213+
```typescript copy
214+
// Track the latest advertised commands for the session.
215+
let availableCommands: acp.AvailableCommand[] = [];
216+
217+
const client: acp.Client = {
218+
async sessionUpdate(params) {
219+
const update = params.update;
220+
221+
if (update.sessionUpdate === "available_commands_update") {
222+
// This notification is a full snapshot—replace any cached list.
223+
availableCommands = update.availableCommands;
224+
for (const command of availableCommands) {
225+
// command.name has no leading slash; invoke it by sending "/<name>" as a prompt.
226+
console.log(`/${command.name} — ${command.description}`);
227+
}
228+
return;
229+
}
230+
231+
// ...handle other updates, such as agent_message_chunk
232+
},
233+
234+
// ...other client methods, such as requestPermission
235+
};
236+
```
237+
238+
To run one of the advertised commands, send its name as a prompt in a single text content block—for example, `{ type: "text", text: "/context" }`—as described in [Using slash commands](#using-slash-commands).
239+
240+
### Commands that cannot be used over ACP
241+
242+
Slash commands that depend on the interactive terminal interface are not handled by the ACP server. This includes commands that open a picker, dialog, or full-screen view, such as `/diff`, `/resume`, `/theme`, `/settings`, `/login`, `/help`, `/tasks`, and `/undo`. As a rule, if a command does not appear in the `available_commands_update` list, it will not run over ACP: the server treats the text as an ordinary prompt and forwards it to the model instead of executing it.
243+
244+
Because ACP clients have no interactive pickers, a built-in command that would normally open a submenu instead returns its options as text. Provide the subcommand explicitly to get a direct result—for example, `/session info` or `/mcp list` rather than `/session` or `/mcp` on its own.
245+
246+
For a complete list of slash commands for {% data variables.copilot.copilot_cli_short %}, see [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-command-reference#slash-commands-in-the-interactive-interface).
247+
137248
## Further reading
138249

139-
* [AUTOTITLE](/copilot/concepts/agents/copilot-in-jetbrains)
140250
* [Official ACP documentation](https://agentclientprotocol.com/protocol/overview)

content/copilot/reference/copilot-cli-reference/cli-command-reference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ When diff mode is open (entered via `/diff`):
193193

194194
## Slash commands in the interactive interface
195195

196+
These are the slash commands you can use from within an interactive CLI session. A subset of these slash commands is available to clients that use the CLI via its ACP server. For more information, see [AUTOTITLE](/copilot/reference/copilot-cli-reference/acp-server).
197+
196198
| Command | Purpose |
197199
|-----------------------------------------------------|---------|
198200
| `/add-dir PATH` | Add a directory to the allowed list for file access. |

0 commit comments

Comments
 (0)