Developers

Connect Buda over ACP

Connect Zed, JetBrains, or your own program to a Buda-hosted agent, step by step.

Agent Client Protocol (ACP) lets you talk to a Buda-hosted agent from Zed, JetBrains, or your own program. Replies, reasoning, and tool calls stream back as standard ACP events, without running the agent or model on your machine.

After setup, your connection looks like this:

Zed / JetBrains / your program
              │ ACP

wss://buda.im/api/acp?agentId=...


Buda agent → cloud sandbox → connected knowledge and integrations

A Buda agent runs in a cloud sandbox. It does not automatically read the local folder open in your editor. To work with a code repository, first connect GitHub to that agent, or place the required content in knowledge sources and integrations the agent can access.

Choose a connection method

Your environmentRecommended methodBridge required?
Zedacpremote + a Zed custom agentYes
JetBrains AI Chatacpremote + ~/.jetbrains/acp.jsonYes
Node.js, scripts, or CIConnect directly with @agentclientprotocol/sdkNo
Another ACP client that supports remote WebSocket and custom headersConnect directly to BudaNo
Browser frontendDo not connect directlyBrowser WebSocket cannot send an Authorization header

Zed and JetBrains custom ACP configurations launch a local command, while Buda exposes a remote WebSocket endpoint. Editor integrations therefore need a small stdio ↔ WebSocket bridge. This guide uses the third-party open-source acpremote tool. It only forwards ACP messages; the Buda agent still runs in the cloud.

Before you begin

Prepare the following:

  • A Buda agent you can access;
  • The agent's agentId;
  • A Buda API key beginning with sk_;
  • For editor setup: Python installed locally and a working acpremote command.

Buda ACP currently auto-approves tool calls instead of showing a permission prompt for each action. Connect only repositories, knowledge sources, and external systems you trust, and use separate API keys for test and production environments.

Step 1: Get the agent ID

Open the agent you want to connect. Its browser URL usually looks like:

https://buda.im/agents/your_agent_id

The value after /agents/ can be used as the agentId. If you created the agent through the REST API, you can also use the id returned by the create-agent endpoint.

For example:

export BUDA_AGENT_ID="your_agent_id"

One ACP connection binds to one agent. To drive another agent, open another connection with a different agentId.

Step 2: Create an API key

Open Settings → API Keys

In the Buda console, open Settings → API Keys, then select New key.

Name the key and choose an expiration

Use a recognizable name such as zed-acp, jetbrains-acp, or ci-acp. Prefer a short expiration period while testing.

Copy the complete key immediately

The complete sk_... value is shown only once. Save it in a password manager or secret store.

Verify the key with the REST API before configuring ACP:

export BUDA_API_KEY="sk_your_api_key"

curl https://buda.im/api/v1/users/me \
  -H "Authorization: Bearer $BUDA_API_KEY"

Continue after the endpoint returns your current user. If it returns 401 Unauthorized, replace or recreate the key first.

Step 3: Build the ACP endpoint

Buda ACP uses these connection values:

SettingValue
WebSocket endpointwss://buda.im/api/acp?agentId=<agentId>
Authentication headerAuthorization: Bearer sk_...
TransportWebSocket
Agents per connection1

Build your full URL:

export BUDA_ACP_URL="wss://buda.im/api/acp?agentId=$BUDA_AGENT_ID"

The API key must belong to a Buda user who can access the requested agent. An invalid key, an unknown agentId, or insufficient access causes initialize to fail and the connection to close.

Step 4: Connect an editor

Install the bridge

Install acpremote as a standalone command:

uv tool install acpremote

If you do not use uv, install it with Python:

python -m pip install --user acpremote

Confirm the editor can find the command:

command -v acpremote
acpremote --help

Copy the absolute path returned by command -v acpremote. An editor launched from the desktop may not inherit the same PATH as your terminal, so an absolute path is the most reliable configuration.

Zed

Open Agent Settings → External Agents → Add Agent → Add Custom Agent, then add this entry to settings.json:

Zed settings.json
{
  "agent_servers": {
    "Buda": {
      "type": "custom",
      "command": "/absolute/path/to/acpremote",
      "args": [
        "mirror",
        "wss://buda.im/api/acp?agentId=your_agent_id",
        "--token-env",
        "BUDA_API_KEY"
      ],
      "env": {
        "BUDA_API_KEY": "sk_your_api_key"
      }
    }
  }
}

Save the settings, start a new Buda thread in the Agent Panel, and send:

Reply with only: Buda ACP connected

A streamed reply confirms the connection works. If Buda does not appear in the agent selector, restart Zed and verify that command points to an existing executable.

JetBrains

In AI Chat, select Add Custom Agent. JetBrains creates and opens ~/.jetbrains/acp.json:

~/.jetbrains/acp.json
{
  "default_mcp_settings": {},
  "agent_servers": {
    "Buda": {
      "command": "/absolute/path/to/acpremote",
      "args": [
        "mirror",
        "wss://buda.im/api/acp?agentId=your_agent_id",
        "--token-env",
        "BUDA_API_KEY"
      ],
      "env": {
        "BUDA_API_KEY": "sk_your_api_key"
      }
    }
  }
}

Save the file, select Buda from the AI Chat agent picker, start a thread, and send a test message.

These minimal configurations store the API key in a local editor configuration file. Do not sync that file into a public repository. Restrict its file permissions, delete or rotate the key when it is no longer needed, and issue separate keys for each team member and environment.

Other editors

If another editor's custom ACP settings also accept command and args, configure it to launch this local command:

BUDA_API_KEY="sk_your_api_key" acpremote mirror \
  "wss://buda.im/api/acp?agentId=your_agent_id" \
  --token-env BUDA_API_KEY

If the client natively supports remote ACP over WebSocket and can send a custom Authorization header during the handshake, skip acpremote and connect directly to Buda.

Step 5: Connect from Node.js or CI

Programmatic clients do not need the stdio bridge. Install the ACP SDK and a Node WebSocket implementation:

npm install @agentclientprotocol/sdk ws

Create buda-acp.mjs:

buda-acp.mjs
import * as acp from "@agentclientprotocol/sdk";
import { createWebSocketStream } from "@agentclientprotocol/sdk/experimental/ws-client";
import WebSocket from "ws";

const apiKey = process.env.BUDA_API_KEY;
const agentId = process.env.BUDA_AGENT_ID;

if (!apiKey || !agentId) {
  throw new Error("Set BUDA_API_KEY and BUDA_AGENT_ID first.");
}

const stream = createWebSocketStream(
  `wss://buda.im/api/acp?agentId=${encodeURIComponent(agentId)}`,
  {
    WebSocket,
    headers: {
      Authorization: `Bearer ${apiKey}`,
    },
  },
);

const client = acp
  .client({ name: "buda-acp-quickstart" })
  .onNotification(acp.methods.client.session.update, ({ params }) => {
    const update = params.update;
    if (update.sessionUpdate === "agent_message_chunk" && update.content.type === "text") {
      process.stdout.write(update.content.text);
    }
  });

const result = await client.connectWith(stream, async (connection) => {
  const initialized = await connection.request(acp.methods.agent.initialize, {
    protocolVersion: acp.PROTOCOL_VERSION,
    clientCapabilities: {},
  });

  const session = await connection.request(acp.methods.agent.session.new, {
    cwd: process.cwd(),
    mcpServers: [],
  });

  const response = await connection.request(acp.methods.agent.session.prompt, {
    sessionId: session.sessionId,
    prompt: [{ type: "text", text: "Reply with only: Buda ACP connected" }],
  });

  return {
    sessionId: session.sessionId,
    stopReason: response.stopReason,
    canLoadSession: initialized.agentCapabilities?.loadSession === true,
  };
});

console.log("\n", result);

Run it:

BUDA_API_KEY="sk_your_api_key" \
BUDA_AGENT_ID="your_agent_id" \
node buda-acp.mjs

You should first see streamed text, followed by a result containing sessionId, stopReason, and canLoadSession: true.

createWebSocketStream currently lives under the SDK's experimental/ws-client export. Check for export-path changes when upgrading @agentclientprotocol/sdk.

How sessions work

A normal ACP call follows this sequence:

  1. initialize negotiates the protocol version and capabilities;
  2. session/new creates a Buda session and returns its sessionId;
  3. session/prompt sends a message;
  4. Multiple session/update notifications stream replies, reasoning, and tool calls;
  5. Save the sessionId. After reconnecting, call initialize again and then use session/load to restore the session;
  6. Send session/cancel when you need to stop an active run.
ACP methodBuda behavior
initializeNegotiates the version and advertises loadSession support
session/newCreates a session for the agent bound to this connection
session/promptSends one turn and streams the result through session/update
session/loadReattaches to an active stream or replays saved session history
session/cancelStops the active run in the requested session

Prompt content currently supports text and resource_link. Image, audio, and embedded-resource content are not yet available.

Troubleshooting

SymptomMost likely causeFix
Buda does not appear in the editorThe editor cannot find acpremoteSet command to the absolute path returned by command -v acpremote, then restart the editor
The connection closes after initializeThe key is invalid or expired, or the agentId is wrongVerify the key with /api/v1/users/me, then copy the ID again from the agent URL
The server reports insufficient accessThe API-key owner does not own the agent and is not a member of its SpaceCreate the key with an authorized account or add the user to the Space
The agent cannot see local project filesBuda uses a remote sandbox, not the editor's local folderConnect GitHub to the agent or upload the files somewhere it can access
A second message reports that a run is already in progressConcurrent session/prompt calls are not supported in one sessionWait for the active run to finish or send session/cancel first
Browser WebSocket authentication failsBrowsers cannot set the WebSocket handshake Authorization headerConnect from a trusted backend or Node.js client; never expose an sk_ key in frontend code
A long run disconnectsA VPN, proxy, or gateway closed the long-lived WebSocketCheck WebSocket support and idle timeouts, then restore the saved sessionId with session/load
Tool calls run without a confirmation dialogBuda ACP currently auto-approves toolsLimit accessible data and integrations, use least-privilege keys, and avoid sensitive systems

In Zed, run ACP: Open ACP Logs from the command palette to inspect messages between Zed and the bridge process. In JetBrains, inspect AI Assistant logs and acpremote standard-error output for startup failures.

Current limitations

  • WebSocket only. Buda ACP does not currently expose the Streamable HTTP profile.
  • No per-action permission prompt. Tool calls are currently auto-approved.
  • One prompt at a time per session. Concurrent prompts are rejected instead of queued.
  • One agent per connection. Connecting multiple agents requires multiple connections.
  • sk_ API keys only. Browser session cookies, OAuth tokens, and internal agent keys are not accepted.
  • The remote sandbox owns the workspace. A client-provided local cwd or MCP server list does not give Buda access to the local machine.

Reference implementations

This setup follows the behavior documented by:

On this page