-
Notifications
You must be signed in to change notification settings - Fork 0
15 agent mode
Agent mode runs Bucket as an ACP (Agent Client Protocol) server for integration with IDEs, editors, and custom tooling. Unlike single-prompt mode (bucket -p, which prints one response and exits), agent mode keeps a persistent process running and communicates through structured JSON-RPC messages.
The Agent Client Protocol (ACP) is a standard for AI agent communication. It defines how clients (IDEs, editors, custom apps) interact with AI agents through a structured JSON-RPC protocol. ACP provides:
- Session management -- create, load, and resume conversations
- Prompt submission -- send user messages and receive streamed responses
- Tool visibility -- see what tools the agent is using in real time
- Thought streams -- observe the agent's reasoning process
- Permission handling -- approve or deny tool executions interactively
stdio is the primary integration mode. The agent exchanges JSON-RPC messages over stdin and stdout:
bucket agent stdioClients that use this mode include:
- IDE extensions (for example, Zed, Neovim, and Emacs)
- Custom automation tools
- ACP client libraries
These options belong to the bucket agent command and apply to every mode. Pass them before the mode name, for example bucket agent --model bucket-build stdio. The stdio subcommand itself takes no options.
| Flag | Description |
|---|---|
-m, --model <MODEL> |
Set the model ID (for example, bucket-build). |
--always-approve |
Auto-approve every tool execution. (Alias: --yolo.) |
--reauth |
Run authentication before starting the agent. |
--agent-profile <PATH> |
Load an agent profile from a file. |
Run the agent as a WebSocket server for remote clients:
bucket agent serve --bind 127.0.0.1:2419 --secret <token>Clients connect over WebSocket and authenticate with the secret token. If you omit --secret, the agent generates a token and prints it at startup; you can also supply one through the BUCKET_AGENT_SECRET environment variable. The agent persists across reconnections, so a client can disconnect and later resume in-flight work.
To reach the agent over the internet instead of the local network, run a WebSocket relay server and have the agent connect to it:
bucket agent headless --bucket-ws-url wss://your-relay.example.com/wsThe agent connects out to your relay, and your web clients connect to the same relay. This is useful for building web UIs where browsers cannot spawn local processes.
Communication follows the JSON-RPC 2.0 format. A typical session lifecycle:
-
Initialize -- client sends
initializewith capabilities -
Create session -- client sends
session/newwith working directory -
Send prompts -- client sends
session/promptwith user messages -
Receive updates -- agent sends
session/updatenotifications with streamed content - Handle permissions -- agent may request tool execution approval
+------------------------------------------+
| ACP Client |
| (IDE, Editor, Custom Application) |
+-------------------+----------------------+
| JSON-RPC over stdio
+-------------------v----------------------+
| bucket agent stdio |
| |
| +---------+ +---------+ +---------+ |
| | Session | | Tools | | MCP | |
| | Manager | | Registry| | Servers | |
| +---------+ +---------+ +---------+ |
+------------------------------------------+
ACP streams structured events. Each session/update notification carries a sessionUpdate field that identifies the update type:
sessionUpdate value |
Description |
|---|---|
agent_message_chunk |
A chunk of the agent's response text. |
agent_thought_chunk |
A chunk of the agent's internal reasoning. |
tool_call |
A new tool invocation (title, kind, status, input). |
tool_call_update |
A status or result update for an in-flight tool call. |
plan |
The agent's execution plan. |
Each update names its type, so a client can render distinct panels for reasoning, tool calls, and response text.
Beyond the base ACP protocol, Bucket defines extension methods under the x.ai/ prefix for SpaceBUCKET-specific functionality. These cover:
| Category | Prefix | Examples |
|---|---|---|
| Filesystem | x.ai/fs/* |
list, exists, read_file, write_file
|
| Git | x.ai/git/* |
status, stage, commit, diffs, discard
|
| Git Worktree | x.ai/git/worktree/* |
create, remove, apply, list, gc
|
| Search | x.ai/search/* |
fuzzy/open, fuzzy/change, content
|
| Terminal | x.ai/terminal/* |
create, kill, output, wait_for_exit
|
| Session Management | x.ai/session/* |
fork, resolve_local_for_worktree_resume
|
| Conversation & History | x.ai/* |
prompt_history, rewind/*, compact_conversation
|
| Authentication | x.ai/auth/* |
get_url, submit_code
|
| Feedback & Telemetry | x.ai/* |
feedback, telemetry/*
|
The tables here show representative methods in each category. The x.ai/* set is SpaceBUCKET-specific and may expand across releases, so treat it as non-exhaustive and discover the available methods from the agent's initialize response.
The agent sends push notifications to clients for real-time updates:
| Notification | Description |
|---|---|
x.ai/search/fuzzy/status |
Fuzzy search results update |
x.ai/git/worktree/status |
Worktree creation progress |
x.ai/fs_notify |
Filesystem change notification |
x.ai/fs/index |
Full file index update |
x.ai/fs/index/delta |
Incremental file index update |
x.ai/session_notification |
Session-specific updates (diff review, retry state, auto-compact) |
x.ai/session/update |
Session update (tool calls, content) |
The session/new request accepts these optional _meta fields:
| Field | Description |
|---|---|
rules |
Extra rules appended to the system prompt. |
systemPromptOverride |
A replacement system prompt. |
agentProfile |
An agent profile, as a name or a JSON object. |
Official SDK libraries are available for multiple languages:
| Language | Package |
|---|---|
| TypeScript | @agentclientprotocol/sdk |
| Rust | agent-client-protocol |
| Python | agent-client-protocol-python |
| Go | acp-go-sdk |
| Kotlin | acp |
| Client | Status |
|---|---|
| Zed | Supported |
| Neovim (CodeCompanion, avante.nvim) | Supported |
| Emacs | Supported |
| marimo notebook | Supported |
| JetBrains | Coming soon |
import { spawn, ChildProcess } from "child_process";
import * as readline from "readline";
class BucketACPChat {
private proc!: ChildProcess;
private sessionId!: string;
private rl!: readline.Interface;
constructor(private cwd = ".") {}
async init() {
this.proc = spawn("bucket", ["agent", "stdio"]);
this.rl = readline.createInterface({ input: this.proc.stdout! });
// Initialize
await this.request("initialize", {
protocolVersion: 1,
clientCapabilities: {
fs: { readTextFile: true, writeTextFile: true },
terminal: true,
},
});
// Create session
const { sessionId } = await this.request("session/new", {
cwd: this.cwd,
mcpServers: [],
});
this.sessionId = sessionId;
return this;
}
private async request(method: string, params: any): Promise<any> {
return new Promise((resolve) => {
const msg = JSON.stringify({ jsonrpc: "2.0", id: 1, method, params });
this.proc.stdin!.write(msg + "\n");
this.rl.once("line", (line) => {
resolve(JSON.parse(line).result || {});
});
});
}
async *streamPrompt(text: string) {
const msg = JSON.stringify({
jsonrpc: "2.0",
id: 1,
method: "session/prompt",
params: {
sessionId: this.sessionId,
prompt: [{ type: "text", text }],
},
});
this.proc.stdin!.write(msg + "\n");
for await (const line of this.rl) {
const data = JSON.parse(line);
if (data.method === "session/update") {
const update = data.params.update;
yield update; // { sessionUpdate, content, title, ... }
} else if (data.result) {
break; // Final response
}
}
}
}
// Usage
const client = await new BucketACPChat(".").init();
for await (const update of client.streamPrompt("List the files in this project")) {
switch (update.sessionUpdate) {
case "agent_message_chunk":
process.stdout.write(update.content?.text || "");
break;
case "agent_thought_chunk":
console.log(`\n[Thinking: ${update.content?.text}]`);
break;
case "tool_call":
console.log(`\n[Tool: ${update.title}]`);
break;
}
}