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

Behaviour for native Elixir ACP agents.

Implement this behaviour and run it with `ExMCP.ACP.Agent`. Prompt callbacks
may either reply immediately or return `{:noreply, state}` and finish the
prompt later with `ExMCP.ACP.Agent.finish_prompt/3` after streaming updates.

# `callback_reply`

```elixir
@type callback_reply() :: map() | [map()] | String.t() | nil
```

# `callback_result`

```elixir
@type callback_result() ::
  {:reply, callback_reply(), state()}
  | {:ok, callback_reply(), state()}
  | {:noreply, state()}
  | {:error, any(), state()}
```

# `context`

```elixir
@type context() :: %{
  :agent =&gt; GenServer.server(),
  :request_id =&gt; integer() | String.t() | nil,
  optional(:prompt_id) =&gt; integer() | String.t() | nil,
  optional(:session_id) =&gt; String.t(),
  optional(:client_info) =&gt; map() | nil,
  optional(:client_capabilities) =&gt; map() | nil,
  optional(:protocol_version) =&gt; pos_integer()
}
```

# `state`

```elixir
@type state() :: any()
```

# `handle_authenticate`
*optional* 

```elixir
@callback handle_authenticate(params :: map(), context(), state()) :: callback_result()
```

Optionally authenticate a client.

# `handle_cancel`
*optional* 

```elixir
@callback handle_cancel(session_id :: String.t(), context(), state()) :: callback_result()
```

Optionally handle `session/cancel`.

If this callback is not implemented, the runtime immediately completes the
active prompt with `"cancelled"`.

# `handle_close_session`
*optional* 

```elixir
@callback handle_close_session(session_id :: String.t(), context(), state()) ::
  callback_result()
```

Optionally close a session.

# `handle_delete_session`
*optional* 

```elixir
@callback handle_delete_session(session_id :: String.t(), context(), state()) ::
  callback_result()
```

Optionally delete a session from session history.

# `handle_fork_session`
*optional* 

```elixir
@callback handle_fork_session(params :: map(), context(), state()) :: callback_result()
```

Optionally fork an existing session into a new independent session.

# `handle_initialize`
*optional* 

```elixir
@callback handle_initialize(params :: map(), context(), state()) :: callback_result()
```

Optionally customize the initialize response.

# `handle_list_sessions`
*optional* 

```elixir
@callback handle_list_sessions(params :: map(), context(), state()) :: callback_result()
```

Optionally list resumable sessions.

# `handle_load_session`
*optional* 

```elixir
@callback handle_load_session(params :: map(), context(), state()) :: callback_result()
```

Optionally load an existing session and replay history.

# `handle_logout`
*optional* 

```elixir
@callback handle_logout(context(), state()) :: callback_result()
```

Optionally log out a client.

# `handle_new_session`

```elixir
@callback handle_new_session(params :: map(), context(), state()) :: callback_result()
```

Called for `session/new`.

Return either a session ID string or a full response map containing
`"sessionId"`.

# `handle_prompt`

```elixir
@callback handle_prompt(
  session_id :: String.t(),
  prompt :: [map()],
  context(),
  state()
) :: callback_result()
```

Called for `session/prompt`.

The `prompt_id` in the context is the ID to pass to
`ExMCP.ACP.Agent.finish_prompt/3` when returning `{:noreply, state}`.

# `handle_resume_session`
*optional* 

```elixir
@callback handle_resume_session(params :: map(), context(), state()) :: callback_result()
```

Optionally resume an existing session without replaying history.

# `handle_set_config_option`
*optional* 

```elixir
@callback handle_set_config_option(
  session_id :: String.t(),
  config_id :: String.t(),
  value :: any(),
  context(),
  state()
) :: callback_result()
```

Optionally update a session config option.

# `handle_set_mode`
*optional* 

```elixir
@callback handle_set_mode(
  session_id :: String.t(),
  mode_id :: String.t(),
  context(),
  state()
) :: callback_result()
```

Optionally switch a session mode.

# `handle_set_model`
*optional* 

```elixir
@callback handle_set_model(
  session_id :: String.t(),
  model_id :: String.t(),
  context(),
  state()
) :: callback_result()
```

Optionally switch a session model.

# `init`

```elixir
@callback init(opts :: keyword()) :: {:ok, state()} | {:error, any()}
```

Called when the handler starts.

# `terminate`
*optional* 

```elixir
@callback terminate(reason :: any(), state()) :: :ok
```

Called when the handler runner terminates.

---

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