Skip to main content

Overview

The ClientSideConnection class provides the client’s view of an ACP connection, allowing clients (such as code editors) to communicate with agents. It implements the Agent interface and manages the bidirectional JSON-RPC communication channel.

Class Definition

class ClientSideConnection implements Agent
This class:
  • Wraps the low-level Connection for client-to-agent communication
  • Routes incoming agent requests to the appropriate Client handler methods
  • Provides methods for clients to call agent endpoints (sessions, prompts, authentication)
  • Handles protocol-level concerns like request validation and method routing

Constructor

ClientSideConnection

Creates a new client-side connection to an agent.
ClientSideConnection(
  Client Function(ClientSideConnection) toAgent,
  AcpStream stream,
)
This establishes the communication channel between a client and agent following the ACP specification.
toAgent
Client Function(ClientSideConnection)
required
A function that creates a Client handler to process incoming agent requests. The function receives the connection instance and returns a Client implementation.
stream
AcpStream
required
The bidirectional message stream for communication. Typically created using ndJsonStream for stdio-based connections.

Agent Interface Methods

The following methods implement the Agent interface and allow clients to make requests to the agent.

initialize

Establishes the connection with an agent and negotiates protocol capabilities.
Future<InitializeResponse> initialize(InitializeRequest params)
params
InitializeRequest
required
The initialization request containing protocol version and client capabilities
InitializeResponse
InitializeResponse
Contains the agent’s protocol version, capabilities, and available authentication methods

newSession

Creates a new conversation session with the agent.
Future<NewSessionResponse> newSession(NewSessionRequest params)
params
NewSessionRequest
required
Request parameters for creating a new session
NewSessionResponse
NewSessionResponse
Contains the unique session ID and session configuration

loadSession

Loads an existing session to resume a previous conversation.
Future<LoadSessionResponse>? loadSession(LoadSessionRequest params)
params
LoadSessionRequest
required
Request parameters containing the session ID to load
LoadSessionResponse
LoadSessionResponse
Contains loaded session information

prompt

Sends a user prompt to the agent for processing.
Future<PromptResponse> prompt(PromptRequest params)
params
PromptRequest
required
The prompt request containing session ID, messages, and context
PromptResponse
PromptResponse
Contains the final stop reason and any result data

cancel

Cancels ongoing operations for a session.
Future<void> cancel(CancelNotification params)
params
CancelNotification
required
Notification containing the session ID to cancel

Session Management Methods

setSessionMode

Sets the operational mode for a session.
Future<SetSessionModeResponse?>? setSessionMode(SetSessionModeRequest params)
params
SetSessionModeRequest
required
Request containing the session ID and desired mode
SetSessionModeResponse
SetSessionModeResponse
Confirms the mode change

setSessionConfigOption

Sets the current value for a session configuration option.
Future<SetSessionConfigOptionResponse> setSessionConfigOption(
  SetSessionConfigOptionRequest params,
)
params
SetSessionConfigOptionRequest
required
Request containing the session ID, option key, and new value
SetSessionConfigOptionResponse
SetSessionConfigOptionResponse
Contains the updated configuration

authenticate

Authenticates the client using the specified authentication method.
Future<AuthenticateResponse?>? authenticate(AuthenticateRequest params)
params
AuthenticateRequest
required
Request containing the authentication method and credentials
AuthenticateResponse
AuthenticateResponse
Confirms authentication success

Unstable Methods

unstableListSessions

Lists existing sessions from the agent.
Future<ListSessionsResponse> unstableListSessions(
  ListSessionsRequest params,
)
params
ListSessionsRequest
required
Request parameters for listing sessions
ListSessionsResponse
ListSessionsResponse
List of available sessions

unstableForkSession

Forks an existing session to create a new independent session.
Future<ForkSessionResponse> unstableForkSession(ForkSessionRequest params)
params
ForkSessionRequest
required
Request containing the source session ID and fork parameters
ForkSessionResponse
ForkSessionResponse
The new forked session information

unstableResumeSession

Resumes an existing session without replaying previous messages.
Future<ResumeSessionResponse> unstableResumeSession(
  ResumeSessionRequest params,
)
params
ResumeSessionRequest
required
Request containing the session ID to resume
ResumeSessionResponse
ResumeSessionResponse
The resumed session information

setSessionModel

Selects the model for a given session.
Future<SetSessionModelResponse?>? setSessionModel(
  SetSessionModelRequest params,
)
params
SetSessionModelRequest
required
Request containing the session ID and model identifier
SetSessionModelResponse
SetSessionModelResponse
Confirms the model selection

Extension Methods

extMethod

Sends an arbitrary request that is not part of the ACP spec.
Future<Map<String, dynamic>>? extMethod(
  String method,
  Map<String, dynamic> params,
)
method
String
required
The extension method name
params
Map<String, dynamic>
required
Method parameters
result
Map<String, dynamic>
Extension method response

extNotification

Sends an arbitrary notification that is not part of the ACP spec.
Future<void>? extNotification(String method, Map<String, dynamic> params)
method
String
required
The extension notification name
params
Map<String, dynamic>
required
Notification parameters

Protocol-Level Methods

sendCancelRequest

Sends the protocol-level $/cancel_request notification.
Future<void> sendCancelRequest(CancelRequestNotification params)
params
CancelRequestNotification
required
Cancellation notification with request ID and optional metadata

cancelPendingRequest

Cancels a pending outbound request and sends $/cancel_request.
Future<bool> cancelPendingRequest(
  RequestId requestId, {
  Map<String, dynamic>? meta,
})
Returns true if the request ID was still pending locally.
requestId
RequestId
required
The ID of the request to cancel
meta
Map<String, dynamic>
Optional metadata to include in the cancellation notification
result
bool
true if the request was pending and was cancelled, false otherwise

Usage Example

import 'dart:io';
import 'package:acp_dart/acp_dart.dart';

class MyClient implements Client {
  late ClientSideConnection connection;

  @override
  Future<RequestPermissionResponse> requestPermission(
    RequestPermissionRequest params,
  ) async {
    // Show permission dialog to user
    print('Agent requests permission: ${params.tool}');
    return RequestPermissionResponse(
      outcome: RequestPermissionOutcome.allow,
    );
  }

  @override
  Future<void> sessionUpdate(SessionNotification params) async {
    // Update UI with session progress
    print('Session update: $params');
  }

  @override
  Future<ReadTextFileResponse>? readTextFile(
    ReadTextFileRequest params,
  ) async {
    final content = await File(params.path).readAsString();
    return ReadTextFileResponse(content: content);
  }

  @override
  Future<WriteTextFileResponse>? writeTextFile(
    WriteTextFileRequest params,
  ) async {
    await File(params.path).writeAsString(params.content);
    return WriteTextFileResponse(success: true);
  }

  // ... implement other Client methods
}

void main() async {
  // Start an agent process
  final agentProcess = await Process.start('path/to/agent', []);

  // Create stdio stream for communication
  final stream = ndJsonStream(
    stdin: agentProcess.stdout,
    stdout: agentProcess.stdin,
  );

  // Create the client-side connection
  final connection = ClientSideConnection(
    (conn) {
      final client = MyClient();
      client.connection = conn;
      return client;
    },
    stream,
  );

  // Initialize the connection
  final initResponse = await connection.initialize(
    InitializeRequest(
      protocolVersion: '1.0',
      capabilities: ClientCapabilities(
        fs: FileSystemCapabilities(
          readTextFile: true,
          writeTextFile: true,
        ),
      ),
    ),
  );

  print('Connected to agent: ${initResponse.protocolVersion}');

  // Create a new session
  final session = await connection.newSession(
    NewSessionRequest(
      mcpServers: [],
    ),
  );

  print('Created session: ${session.sessionId}');

  // Send a prompt
  final response = await connection.prompt(
    PromptRequest(
      sessionId: session.sessionId,
      messages: [
        ContentMessage(
          role: Role.user,
          content: [TextContent(text: 'Hello, agent!')],
        ),
      ],
    ),
  );

  print('Prompt complete: ${response.stopReason}');
}

Request Routing

The ClientSideConnection automatically routes incoming JSON-RPC requests to the appropriate Client methods:

Error Handling

The connection automatically handles errors and converts them to JSON-RPC error responses:
  • Methods returning null are treated as not supported and return MethodNotFound
  • Unknown methods return MethodNotFound errors
  • Protocol-level notifications starting with $/ may be safely ignored
  • Extension methods/notifications starting with _ are routed to extMethod()/extNotification()

See Also

  • Client - The Client interface implemented by client handlers
  • Agent - The Agent interface this class implements
  • Connection - The underlying connection class
  • AgentSideConnection - The agent-side equivalent

Build docs developers (and LLMs) love