# `ExMCP.ACP.Agent`
[🔗](https://github.com/azmaveth/ex_mcp/blob/v1.0.0/lib/ex_mcp/acp/agent.ex#L1)

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

## Resource limits

`:max_frame_bytes` and `:max_pending_requests` default to 1 MiB and 1,024.
`:pending_request_timeout` bounds client-bound requests and pending prompts;
`:handler_request_timeout` bounds handler callbacks. Both default to 30 seconds.

# `agent_message`

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

Streams an `agent_message_chunk` update.

# `agent_thought`

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

Streams an `agent_thought_chunk` update.

# `available_commands`

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

Sends an `available_commands_update` update.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `config_options`

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

Sends a `config_option_update` update.

# `current_mode`

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

Sends a `current_mode_update` update.

# `finish_prompt`

```elixir
@spec finish_prompt(
  GenServer.server(),
  integer() | String.t() | nil,
  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`

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

Sends a `plan` update.

# `read_text_file`

```elixir
@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`

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

Requests permission from the ACP client.

# `run`

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

Starts an ACP agent and blocks until it exits.

Intended for stdio command-line entrypoints.

# `session_info`

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

Sends a `session_info_update` update.

# `session_update`

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

Sends a raw `session/update` notification.

# `start_link`

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

Starts an ACP agent runtime.

# `status`

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

Returns the runtime status.

# `stop`

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

Stops an ACP agent runtime.

# `terminal_create`

```elixir
@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`

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

Kills a terminal command.

# `terminal_output`

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

Requests terminal output from the ACP client.

# `terminal_release`

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

Releases a terminal.

# `terminal_wait_for_exit`

```elixir
@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`

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

Sends a `tool_call` update.

# `tool_call_update`

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

Sends a `tool_call_update` update.

# `usage`

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

Sends a `usage_update` update.

# `write_text_file`

```elixir
@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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
