ExMCP.ACP.Client (ex_mcp v0.9.2)

View Source

GenServer client for the Agent Client Protocol (ACP).

Manages connections to ACP-compatible coding agents over stdio, handling the initialize handshake, session lifecycle, and bidirectional communication (streaming updates from agent, permission/file requests from agent).

Usage

{:ok, client} = ExMCP.ACP.Client.start_link(
  command: ["gemini", "--acp"],
  handler: MyApp.ACPHandler
)

{:ok, %{"sessionId" => sid}} = ExMCP.ACP.Client.new_session(client, "/path/to/project")
{:ok, %{"stopReason" => _}} = ExMCP.ACP.Client.prompt(client, sid, "Fix the bug in auth.ex")

Options

  • :command — command list for the agent subprocess (required)
  • :handler — module implementing ExMCP.ACP.Client.Handler (default: DefaultHandler)
  • :handler_opts — options passed to handler.init/1 (default: [])
  • :event_listener — PID to receive {:acp_session_update, session_id, update} messages
  • :client_info%{"name" => ..., "version" => ...} (default: %{"name" => "ex_mcp", "version" => "0.1.0"})
  • :capabilities — client capabilities map
  • :protocol_version — integer (default: 1)
  • :name — GenServer name registration

Summary

Functions

Returns the agent's capabilities from the initialize handshake.

Returns the agent's authentication methods from the initialize handshake.

Cancels the current prompt in a session (fire-and-forget).

Returns a specification to start this module under a supervisor.

Closes an active session and frees agent-side resources.

Disconnects from the agent.

Lists available sessions from the agent. Stabilized in ACP spec March 9, 2026.

Loads an existing session and replays previous messages when the agent supports it.

Logs out of the current authenticated state if the agent supports auth.logout.

Creates a new agent session.

Sends a prompt to the agent and blocks until the response arrives.

Resumes an existing session without replaying previous messages.

Sets a config option for a session.

Sets the agent mode for a session.

Starts the ACP client and connects to the agent.

Returns the client connection status.

Functions

agent_capabilities(client)

@spec agent_capabilities(GenServer.server()) :: {:ok, map() | nil}

Returns the agent's capabilities from the initialize handshake.

auth_methods(client)

@spec auth_methods(GenServer.server()) :: {:ok, [map()]}

Returns the agent's authentication methods from the initialize handshake.

authenticate(client, method_id_or_params \\ %{}, opts \\ [])

@spec authenticate(GenServer.server(), String.t() | map(), keyword()) ::
  {:ok, map() | nil} | {:error, any()}

Authenticates with the agent.

Pass either a method ID advertised in the initialize response's "authMethods" list or a full params map for adapter compatibility.

cancel(client, session_id)

@spec cancel(GenServer.server(), String.t()) :: :ok

Cancels the current prompt in a session (fire-and-forget).

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

close_session(client, session_id, opts \\ [])

@spec close_session(GenServer.server(), String.t(), keyword()) ::
  {:ok, map() | nil} | {:error, any()}

Closes an active session and frees agent-side resources.

disconnect(client)

@spec disconnect(GenServer.server()) :: :ok

Disconnects from the agent.

end_session(client, session_id)

@spec end_session(GenServer.server(), String.t()) ::
  :ok | {:ok, map() | nil} | {:error, any()}

Ends a session.

Uses session/close when advertised by the agent, otherwise preserves the historical local telemetry-only behavior.

list_sessions(client, opts \\ [])

@spec list_sessions(
  GenServer.server(),
  keyword()
) :: {:ok, map()} | {:error, any()}

Lists available sessions from the agent. Stabilized in ACP spec March 9, 2026.

load_session(client, session_id, cwd \\ nil, opts \\ [])

@spec load_session(GenServer.server(), String.t(), String.t() | nil, keyword()) ::
  {:ok, map()} | {:error, any()}

Loads an existing session and replays previous messages when the agent supports it.

logout(client, opts \\ [])

@spec logout(
  GenServer.server(),
  keyword()
) :: {:ok, map() | nil} | {:error, any()}

Logs out of the current authenticated state if the agent supports auth.logout.

new_session(client, cwd \\ nil, opts \\ [])

@spec new_session(GenServer.server(), String.t() | nil, keyword()) ::
  {:ok, map()} | {:error, any()}

Creates a new agent session.

prompt(client, session_id, content, opts \\ [])

@spec prompt(GenServer.server(), String.t(), String.t() | [map()], keyword()) ::
  {:ok, map()} | {:error, any()}

Sends a prompt to the agent and blocks until the response arrives.

Streaming session/update notifications are delivered to the handler and event listener as they arrive. The caller is unblocked when the agent sends the JSON-RPC result for the prompt request.

resume_session(client, session_id, cwd \\ nil, opts \\ [])

@spec resume_session(GenServer.server(), String.t(), String.t() | nil, keyword()) ::
  {:ok, map() | nil} | {:error, any()}

Resumes an existing session without replaying previous messages.

set_config_option(client, session_id, config_id, value)

@spec set_config_option(GenServer.server(), String.t(), String.t(), any()) ::
  {:ok, map()} | {:error, any()}

Sets a config option for a session.

set_mode(client, session_id, mode_id)

@spec set_mode(GenServer.server(), String.t(), String.t()) ::
  {:ok, map()} | {:error, any()}

Sets the agent mode for a session.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Starts the ACP client and connects to the agent.

status(client)

@spec status(GenServer.server()) :: atom()

Returns the client connection status.