Skip to main content

Overview

The Agent interface defines the methods that all ACP-compliant agents must implement. These methods handle the lifecycle of the connection, session management, prompt processing, and cancellation.
export interface Agent {
  // Required methods
  initialize(params: InitializeRequest): Promise<InitializeResponse>;
  newSession(params: NewSessionRequest): Promise<NewSessionResponse>;
  authenticate(params: AuthenticateRequest): Promise<AuthenticateResponse | void>;
  prompt(params: PromptRequest): Promise<PromptResponse>;
  cancel(params: CancelNotification): Promise<void>;

  // Optional methods
  loadSession?(params: LoadSessionRequest): Promise<LoadSessionResponse>;
  setSessionMode?(params: SetSessionModeRequest): Promise<SetSessionModeResponse | void>;
  setSessionConfigOption?(params: SetSessionConfigOptionRequest): Promise<SetSessionConfigOptionResponse>;
  unstable_forkSession?(params: ForkSessionRequest): Promise<ForkSessionResponse>;
  unstable_listSessions?(params: ListSessionsRequest): Promise<ListSessionsResponse>;
  unstable_resumeSession?(params: ResumeSessionRequest): Promise<ResumeSessionResponse>;
  unstable_setSessionModel?(params: SetSessionModelRequest): Promise<SetSessionModelResponse | void>;
  extMethod?(method: string, params: Record<string, unknown>): Promise<Record<string, unknown>>;
  extNotification?(method: string, params: Record<string, unknown>): Promise<void>;
}

Required Methods

initialize

Establishes the connection with a client and negotiates protocol capabilities.
async initialize(
  params: InitializeRequest
): Promise<InitializeResponse>
params.protocolVersion
string
required
The protocol version requested by the client
params.clientCapabilities
object
required
Capabilities advertised by the client (file system access, terminal support, etc.)
protocolVersion
string
required
The protocol version the agent will use (should match the client’s version)
agentCapabilities
object
required
Capabilities advertised by the agent (session loading, modes, etc.)
This method is called once at the beginning of the connection to:
  • Negotiate the protocol version to use
  • Exchange capability information between client and agent
  • Determine available authentication methods
See protocol docs: Initialization

Example

async initialize(params: acp.InitializeRequest): Promise<acp.InitializeResponse> {
  return {
    protocolVersion: acp.PROTOCOL_VERSION,
    agentCapabilities: {
      loadSession: true,
      sessionModes: true,
    },
    availableModes: [
      { id: "code", name: "Code", description: "Full coding capabilities" },
      { id: "ask", name: "Ask", description: "Question answering only" },
    ],
  };
}

newSession

Creates a new conversation session with the agent.
async newSession(
  params: NewSessionRequest
): Promise<NewSessionResponse>
params.workingDirectory
string
Optional working directory for the session
params.mcpServers
MCPServerConfig[]
MCP servers to connect to for this session
sessionId
string
required
A unique identifier for the new session
availableModes
Mode[]
Optional list of available modes for this session
currentMode
string
The initial mode for this session
Sessions represent independent conversation contexts with their own history and state. The agent should:
  • Create a new session context
  • Connect to any specified MCP servers
  • Return a unique session ID for future requests
May throw an auth_required error if the agent requires authentication. See protocol docs: Session Setup

Example

async newSession(params: acp.NewSessionRequest): Promise<acp.NewSessionResponse> {
  const sessionId = crypto.randomUUID();
  
  this.sessions.set(sessionId, {
    workingDirectory: params.workingDirectory,
    history: [],
    pendingPrompt: null,
  });

  return {
    sessionId,
    currentMode: "code",
  };
}

authenticate

Authenticates the client using the specified authentication method.
async authenticate(
  params: AuthenticateRequest
): Promise<AuthenticateResponse | void>
params.method
string
required
The authentication method ID that was advertised during initialization
params.credentials
object
Optional credentials provided by the client
Called when the agent requires authentication before allowing session creation. After successful authentication, the client can proceed to create sessions with newSession without receiving an auth_required error. See protocol docs: Initialization

Example

async authenticate(params: acp.AuthenticateRequest): Promise<void> {
  // No authentication needed in this example
  return;
}

prompt

Processes a user prompt within a session.
async prompt(
  params: PromptRequest
): Promise<PromptResponse>
params.sessionId
string
required
The session ID to process the prompt in
params.messages
Message[]
required
The user messages with optional context (files, images, etc.)
stopReason
StopReason
required
The reason the prompt turn ended: “end_turn”, “cancelled”, or “error”
This method handles the whole lifecycle of a prompt:
  • Receives user messages with optional context
  • Processes the prompt using language models
  • Reports language model content and tool calls to the client
  • Requests permission to run tools
  • Executes any requested tool calls
  • Returns when the turn is complete with a stop reason
See the Handling Prompts guide for detailed information. See protocol docs: Prompt Turn

Example

async prompt(params: acp.PromptRequest): Promise<acp.PromptResponse> {
  const session = this.sessions.get(params.sessionId);
  if (!session) {
    throw new Error(`Session ${params.sessionId} not found`);
  }

  session.pendingPrompt = new AbortController();

  try {
    // Process the prompt with your LLM
    await this.processPrompt(params, session);
    return { stopReason: "end_turn" };
  } catch (err) {
    if (session.pendingPrompt.signal.aborted) {
      return { stopReason: "cancelled" };
    }
    throw err;
  } finally {
    session.pendingPrompt = null;
  }
}

cancel

Cancels ongoing operations for a session.
async cancel(
  params: CancelNotification
): Promise<void>
params.sessionId
string
required
The session ID to cancel operations for
This is a notification sent by the client to cancel an ongoing prompt turn. Upon receiving this notification, the agent SHOULD:
  • Stop all language model requests as soon as possible
  • Abort all tool call invocations in progress
  • Send any pending session/update notifications
  • Respond to the original session/prompt request with StopReason::Cancelled
See protocol docs: Cancellation

Example

async cancel(params: acp.CancelNotification): Promise<void> {
  const session = this.sessions.get(params.sessionId);
  session?.pendingPrompt?.abort();
}

Optional Methods

loadSession

Loads an existing session to resume a previous conversation.
loadSession?(
  params: LoadSessionRequest
): Promise<LoadSessionResponse>
params.sessionId
string
required
The session ID to load
params.mcpServers
MCPServerConfig[]
MCP servers to connect to for this session
This method is only available if the agent advertises the loadSession capability. The agent should:
  • Restore the session context and conversation history
  • Connect to the specified MCP servers
  • Stream the entire conversation history back to the client via notifications
See protocol docs: Loading Sessions

setSessionMode

Sets the operational mode for a session.
setSessionMode?(
  params: SetSessionModeRequest
): Promise<SetSessionModeResponse | void>
params.sessionId
string
required
The session ID to update
params.mode
string
required
The mode to switch to (must be one of the advertised modes)
Allows switching between different agent modes (e.g., “ask”, “architect”, “code”) that affect system prompts, tool availability, and permission behaviors. This method can be called at any time during a session, whether the agent is idle or actively generating a turn. See protocol docs: Session Modes

Unstable Methods

The following methods are marked as UNSTABLE and may be removed or changed at any point:
  • unstable_forkSession: Forks an existing session to create a new independent session
  • unstable_listSessions: Lists existing sessions from the agent
  • unstable_resumeSession: Resumes an existing session without returning previous messages
  • unstable_setSessionModel: Selects a model for a given session
These are experimental features not yet part of the official ACP specification.

Extension Methods

  • extMethod: Allows custom request handlers not part of the ACP specification
  • extNotification: Allows custom notification handlers not part of the ACP specification

Complete Example

import * as acp from "@agentprotocol/acp";

interface AgentSession {
  workingDirectory?: string;
  history: acp.Message[];
  pendingPrompt: AbortController | null;
}

class MyAgent implements acp.Agent {
  private connection: acp.AgentSideConnection;
  private sessions: Map<string, AgentSession>;

  constructor(connection: acp.AgentSideConnection) {
    this.connection = connection;
    this.sessions = new Map();
  }

  async initialize(params: acp.InitializeRequest): Promise<acp.InitializeResponse> {
    return {
      protocolVersion: acp.PROTOCOL_VERSION,
      agentCapabilities: {
        loadSession: false,
      },
    };
  }

  async newSession(params: acp.NewSessionRequest): Promise<acp.NewSessionResponse> {
    const sessionId = crypto.randomUUID();
    this.sessions.set(sessionId, {
      workingDirectory: params.workingDirectory,
      history: [],
      pendingPrompt: null,
    });
    return { sessionId };
  }

  async authenticate(params: acp.AuthenticateRequest): Promise<void> {
    // Implement authentication if needed
  }

  async prompt(params: acp.PromptRequest): Promise<acp.PromptResponse> {
    const session = this.sessions.get(params.sessionId);
    if (!session) {
      throw new Error(`Session ${params.sessionId} not found`);
    }

    session.pendingPrompt = new AbortController();

    try {
      // Process the prompt with your LLM
      await this.processPrompt(params, session);
      return { stopReason: "end_turn" };
    } catch (err) {
      if (session.pendingPrompt.signal.aborted) {
        return { stopReason: "cancelled" };
      }
      throw err;
    } finally {
      session.pendingPrompt = null;
    }
  }

  async cancel(params: acp.CancelNotification): Promise<void> {
    this.sessions.get(params.sessionId)?.pendingPrompt?.abort();
  }

  private async processPrompt(
    params: acp.PromptRequest,
    session: AgentSession
  ): Promise<void> {
    // Your prompt processing logic here
  }
}

Build docs developers (and LLMs) love