ExMCP.ACP.Agent (ex_mcp v0.10.0)

View Source

Runtime for building native Elixir Agent Client Protocol agents.

ExMCP.ACP.Agent is the ACP counterpart to an MCP server: it receives client requests such as session/new and session/prompt, streams session/update notifications, and may request client-side filesystem, terminal, or permission operations.

Prompt callbacks may return immediately or keep the JSON-RPC request pending:

def handle_prompt(session_id, prompt, ctx, state) do
  Task.start(fn ->
    ExMCP.ACP.Agent.agent_message(ctx.agent, session_id, "Working...")
    ExMCP.ACP.Agent.finish_prompt(ctx.agent, ctx.prompt_id, "end_turn")
  end)

  {:noreply, state}
end

Summary

Functions

Streams an agent_message_chunk update.

Streams an agent_thought_chunk update.

Sends an available_commands_update update.

Returns a specification to start this module under a supervisor.

Sends a config_option_update update.

Sends a current_mode_update update.

Completes a pending session/prompt request.

Requests text file contents from the ACP client.

Starts an ACP agent and blocks until it exits.

Sends a session_info_update update.

Sends a raw session/update notification.

Starts an ACP agent runtime.

Returns the runtime status.

Stops an ACP agent runtime.

Requests terminal creation from the ACP client.

Requests terminal output from the ACP client.

Requests that the ACP client write a text file.

Functions

agent_message(agent, session_id, content, opts \\ [])

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

Streams an agent_message_chunk update.

agent_thought(agent, session_id, content, opts \\ [])

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

Streams an agent_thought_chunk update.

available_commands(agent, session_id, commands, opts \\ [])

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

Sends an available_commands_update update.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

config_options(agent, session_id, options, opts \\ [])

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

Sends a config_option_update update.

current_mode(agent, session_id, mode_id, opts \\ [])

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

Sends a current_mode_update update.

finish_prompt(agent, prompt_id, result_or_stop_reason, opts \\ [])

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

Completes a pending session/prompt request.

result_or_stop_reason may be a stop reason string or a response map containing "stopReason".

plan(agent, session_id, entries, opts \\ [])

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

Sends a plan update.

read_text_file(agent, session_id, path, opts \\ [])

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

Requests text file contents from the ACP client.

request_permission(agent, session_id, tool_call, options, opts \\ [])

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

Requests permission from the ACP client.

run(opts)

@spec run(keyword()) :: :ok | {:error, any()}

Starts an ACP agent and blocks until it exits.

Intended for stdio command-line entrypoints.

session_info(agent, session_id, info, opts \\ [])

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

Sends a session_info_update update.

session_update(agent, session_id, update, opts \\ [])

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

Sends a raw session/update notification.

start_link(opts)

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

Starts an ACP agent runtime.

status(agent)

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

Returns the runtime status.

stop(agent)

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

Stops an ACP agent runtime.

terminal_create(agent, session_id, command_or_params, opts \\ [])

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

Requests terminal creation from the ACP client.

terminal_kill(agent, session_id, terminal_id, opts \\ [])

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

Kills a terminal command.

terminal_output(agent, session_id, terminal_id, opts \\ [])

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

Requests terminal output from the ACP client.

terminal_release(agent, session_id, terminal_id, opts \\ [])

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

Releases a terminal.

terminal_wait_for_exit(agent, session_id, terminal_id, opts \\ [])

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

Waits for a terminal command to exit.

tool_call(agent, session_id, tool_call, opts \\ [])

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

Sends a tool_call update.

tool_call_update(agent, session_id, update, opts \\ [])

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

Sends a tool_call_update update.

usage(agent, session_id, used, size, opts \\ [])

@spec usage(
  GenServer.server(),
  String.t(),
  non_neg_integer(),
  non_neg_integer(),
  keyword()
) ::
  :ok | {:error, any()}

Sends a usage_update update.

write_text_file(agent, session_id, path, content, opts \\ [])

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

Requests that the ACP client write a text file.