> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/block/goose/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Client Protocol (ACP)

> Integrate Goose with IDEs and applications using the standardized ACP protocol

The Agent Client Protocol (ACP) is a standardized JSON-RPC protocol for AI agent communication. Goose implements ACP for rich, bidirectional integration with IDEs, desktop applications, and other tools.

## Overview

ACP provides:

* **Bidirectional communication**: Agents can request permissions and receive cancellations
* **Rich tool call handling**: Detailed status updates, locations, and content
* **Session management**: Create, load, and resume sessions with full history
* **MCP server integration**: Dynamically add MCP servers to sessions
* **Streaming responses**: Real-time updates as the agent works

## ACP vs REST API

| Feature            | ACP (stdio/WebSocket)                      | REST API (goose-server)  |
| ------------------ | ------------------------------------------ | ------------------------ |
| **Use case**       | IDE plugins, desktop apps, embedded agents | Web apps, simple clients |
| **Transport**      | stdio, WebSocket, HTTP                     | HTTP only                |
| **Permissions**    | Interactive prompts                        | Not supported            |
| **Tool locations** | File paths with line numbers               | Not provided             |
| **Streaming**      | JSON-RPC notifications                     | Server-Sent Events       |
| **Session resume** | Full conversation history                  | Session ID only          |

<Tip>
  Use ACP for desktop applications and IDE integrations where you need rich tool feedback and permission prompts. Use the REST API for simpler web-based integrations.
</Tip>

## Quick Start

### Running ACP Server

```bash theme={null}
# Start Goose as an ACP server on stdio
goose acp --with-builtin developer,memory

# Or programmatically
cargo run -p goose-cli -- acp --with-builtin developer
```

The server communicates via stdin/stdout using JSON-RPC.

### Python Client Example

See `test_acp_client.py` in the source repository for a complete example:

```python theme={null}
import subprocess
import json

class AcpClient:
    def __init__(self):
        self.process = subprocess.Popen(
            ['goose', 'acp', '--with-builtin', 'developer'],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            text=True
        )
        self.request_id = 0
    
    def send_request(self, method, params=None):
        self.request_id += 1
        request = {
            "jsonrpc": "2.0",
            "method": method,
            "id": self.request_id
        }
        if params:
            request["params"] = params
        
        self.process.stdin.write(json.dumps(request) + "\n")
        self.process.stdin.flush()
        
        response = json.loads(self.process.stdout.readline())
        return response

# Initialize connection
client = AcpClient()
client.send_request("initialize", {
    "protocolVersion": "v1",
    "clientInfo": {"name": "my-client", "version": "1.0.0"}
})

# Create session
session = client.send_request("session/new", {
    "cwd": "/path/to/project"
})

# Send prompt
client.send_request("session/prompt", {
    "sessionId": session["result"]["sessionId"],
    "prompt": [{"type": "text", "text": "List files"}]
})
```

## Protocol Methods

### Connection Lifecycle

#### initialize

Establish connection and exchange capabilities.

**Request:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "initialize",
  "id": 1,
  "params": {
    "protocolVersion": "v1",
    "clientCapabilities": {},
    "clientInfo": {
      "name": "vscode-goose",
      "version": "1.0.0"
    }
  }
}
```

**Response:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "v1",
    "agentCapabilities": {
      "loadSession": true,
      "promptCapabilities": {
        "image": true,
        "audio": false,
        "embeddedContext": true
      },
      "mcpCapabilities": {
        "http": true
      }
    },
    "authMethods": [
      {
        "id": "goose-provider",
        "name": "Configure Provider",
        "description": "Run `goose configure` to set up your AI provider"
      }
    ]
  }
}
```

### Session Management

#### session/new

Create a new session with optional MCP servers.

**Request:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "session/new",
  "id": 2,
  "params": {
    "cwd": "/home/user/project",
    "mcpServers": [
      {
        "type": "stdio",
        "name": "github",
        "command": "uvx",
        "args": ["github-mcp-server"],
        "env": [{"name": "GITHUB_TOKEN", "value": "ghp_..."}]
      }
    ]
  }
}
```

**Response:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "models": {
      "current": "claude-sonnet-4-20250514",
      "available": [
        {"id": "claude-sonnet-4-20250514", "name": "Claude Sonnet 4"},
        {"id": "gpt-4o", "name": "GPT-4o"}
      ]
    }
  }
}
```

#### session/load

Load an existing session by ID.

**Request:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "session/load",
  "id": 3,
  "params": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "cwd": "/home/user/project"
  }
}
```

**Response:**
Returns full conversation history as a series of `session/notification` notifications, followed by the response:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "models": { /* same as session/new */ }
  }
}
```

#### session/prompt

Send a prompt and receive streaming responses.

**Request:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "session/prompt",
  "id": 4,
  "params": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "prompt": [
      {"type": "text", "text": "What files are in this directory?"},
      {"type": "image", "data": "base64...", "mimeType": "image/png"}
    ]
  }
}
```

**Response:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "stopReason": "endTurn"
  }
}
```

<Info>
  The response is sent only after all streaming notifications complete. Use notifications to receive real-time updates.
</Info>

#### session/cancel

Cancel an in-progress prompt.

**Notification:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "session/cancel",
  "params": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000"
  }
}
```

### Notifications (Agent → Client)

Notifications stream updates during `session/prompt`.

#### session/notification - Agent Message

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "session/notification",
  "params": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "update": {
      "sessionUpdate": "agentMessageChunk",
      "chunk": {
        "content": {"type": "text", "text": "Let me check the files"}
      }
    }
  }
}
```

#### session/notification - Tool Call

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "session/notification",
  "params": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "update": {
      "sessionUpdate": "toolCall",
      "toolCall": {
        "id": "call_abc123",
        "title": "Developer: List Files",
        "status": "pending"
      }
    }
  }
}
```

#### session/notification - Tool Call Update

Includes file locations for editor integration:

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "session/notification",
  "params": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "update": {
      "sessionUpdate": "toolCallUpdate",
      "toolCallUpdate": {
        "id": "call_abc123",
        "fields": {
          "status": "completed",
          "content": [
            {"type": "text", "text": "Found 5 files"}
          ],
          "locations": [
            {"path": "/home/user/project/main.rs", "line": 1}
          ]
        }
      }
    }
  }
}
```

<Tip>
  The `locations` field enables IDE integrations to highlight or navigate to files modified by tools.
</Tip>

#### requestPermission - Interactive Approval

For sensitive operations, the agent requests permission:

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "requestPermission",
  "id": 100,
  "params": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "toolCallUpdate": {
      "id": "call_xyz789",
      "fields": {
        "title": "Execute Command",
        "status": "pending",
        "rawInput": {"command": "rm -rf /"},
        "content": [{"type": "text", "text": "Delete all files?"}]
      }
    },
    "options": [
      {"id": "allow_always", "name": "Allow Always", "kind": "allowAlways"},
      {"id": "allow_once", "name": "Allow Once", "kind": "allowOnce"},
      {"id": "reject_once", "name": "Reject Once", "kind": "rejectOnce"},
      {"id": "reject_always", "name": "Reject Always", "kind": "rejectAlways"}
    ]
  }
}
```

**Client Response:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 100,
  "result": {
    "outcome": {
      "type": "selected",
      "optionId": "allow_once"
    }
  }
}
```

## Custom Methods

Goose extends ACP with custom methods for additional functionality.

### \_extensions/add

Add an MCP extension to a running session:

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "_extensions/add",
  "id": 5,
  "params": {
    "sessionId": "550e8400-e29b-41d4-a716-446655440000",
    "config": {
      "type": "stdio",
      "name": "slack",
      "cmd": "uvx",
      "args": ["mcp-slack"]
    }
  }
}
```

### \_session/list

List all sessions:

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "_session/list",
  "id": 6
}
```

**Response:**

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "sessions": [
      {
        "sessionId": "550e8400-e29b-41d4-a716-446655440000",
        "title": "My Project",
        "cwd": "/home/user/project",
        "updatedAt": "2026-03-04T12:00:00Z"
      }
    ]
  }
}
```

### Other Custom Methods

* `_session/get`: Get full session details
* `_session/delete`: Delete a session
* `_session/export`: Export session data
* `_session/import`: Import session data
* `_extensions/remove`: Remove an extension
* `_tools`: List available tools
* `_resource/read`: Read an MCP resource
* `_working_dir/update`: Change session working directory
* `_config/extensions`: Get extension configuration

## Transport Options

### stdio (Default)

Communicate via standard input/output:

```bash theme={null}
goose acp --with-builtin developer
```

Ideal for:

* CLI tools
* Editor plugins (VS Code, Neovim)
* Process-based integrations

### WebSocket (Future)

WebSocket transport for browser-based clients:

```bash theme={null}
goose acp --transport websocket --port 8080
```

### HTTP (Future)

HTTP transport for stateless clients:

```bash theme={null}
goose acp --transport http --port 8080
```

## Implementation Details

### Source Code

* ACP server: `crates/goose-acp/src/server.rs`
* CLI integration: `crates/goose-cli/src/cli.rs` (Command::Acp)
* Protocol library: `sacp` crate (vendored)
* Custom methods: `crates/goose-acp/src/custom_requests.rs`
* Test client: `test_acp_client.py`

### Tool Location Extraction

Goose automatically extracts file locations from tool responses for developer tools:

```rust theme={null}
// crates/goose-acp/src/server.rs
fn extract_tool_locations(
    tool_request: &ToolRequest,
    tool_response: &ToolResponse,
) -> Vec<ToolCallLocation> {
    // Parse tool output for file paths and line numbers
    // Returns locations for IDE navigation
}
```

Supported tools:

* `write`: File creation (line 1)
* `edit`: File modification (parsed from output)
* `view`: File viewing (parsed from output)

### Session State Management

ACP sessions are isolated per connection:

```rust theme={null}
struct GooseAcpSession {
    agent: Arc<Agent>,
    messages: Conversation,
    tool_requests: HashMap<String, ToolRequest>,
    cancel_token: Option<CancellationToken>,
}
```

Sessions accumulate until the transport closes.

## Best Practices

### Error Handling

Handle JSON-RPC errors gracefully:

```python theme={null}
response = client.send_request("session/prompt", params)
if "error" in response:
    print(f"Error {response['error']['code']}: {response['error']['message']}")
    # Fallback logic
```

### Notification Buffering

Buffer notifications during streaming:

```python theme={null}
def collect_response(client, request_id):
    notifications = []
    while True:
        line = client.process.stdout.readline()
        msg = json.loads(line)
        
        if "method" in msg:  # Notification
            notifications.append(msg)
        elif msg.get("id") == request_id:  # Response
            return msg, notifications
```

### Cancellation

Implement cancellation for long-running operations:

```python theme={null}
import threading

def prompt_with_timeout(client, session_id, prompt, timeout=30):
    def cancel():
        time.sleep(timeout)
        client.send_notification("session/cancel", {"sessionId": session_id})
    
    threading.Thread(target=cancel, daemon=True).start()
    return client.send_request("session/prompt", {...})
```

## Resources

* ACP Specification: [Anthropic Cookbook](https://github.com/anthropics/anthropic-cookbook/tree/main/misc/agent_client_protocol)
* Goose ACP Implementation: `crates/goose-acp/`
* Test Client: `test_acp_client.py`
* sacp Library: `vendor/sacp/` (Rust ACP implementation)
