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

ACP-specific message encoding.

Delegates JSON-RPC 2.0 framing to internal helpers and adds ACP
method-specific encoding on top.

ACP uses integer protocol versions (default: 1) rather than MCP's date-based strings.

# `encode_agent_message_chunk`

```elixir
@spec encode_agent_message_chunk(String.t(), String.t() | map(), keyword() | map()) ::
  map()
```

Encodes an `agent_message_chunk` update notification.

# `encode_agent_thought_chunk`

```elixir
@spec encode_agent_thought_chunk(String.t(), String.t() | map(), keyword() | map()) ::
  map()
```

Encodes an `agent_thought_chunk` update notification.

# `encode_authenticate`

```elixir
@spec encode_authenticate(String.t() | map()) :: map()
```

Encodes an `authenticate` request.

ACP v1 authentication uses a `"methodId"` selected from the agent's
`authMethods` initialize response. A map may still be passed for adapter
compatibility.

## Parameters

- `method_id_or_params` — auth method ID string or full params map

# `encode_available_commands_update`

```elixir
@spec encode_available_commands_update(String.t(), [map()]) :: map()
```

Encodes an `available_commands_update` notification.

# `encode_cancel_request`

```elixir
@spec encode_cancel_request(integer() | String.t() | nil) :: map()
```

Encodes a `$/cancel_request` notification for a specific JSON-RPC request.

# `encode_config_option_update`

```elixir
@spec encode_config_option_update(String.t(), [map()]) :: map()
```

Encodes a `config_option_update` notification.

# `encode_current_mode_update`

```elixir
@spec encode_current_mode_update(String.t(), String.t()) :: map()
```

Encodes a `current_mode_update` notification.

# `encode_error`

Encodes a JSON-RPC error response.

# `encode_file_read_request`

```elixir
@spec encode_file_read_request(String.t(), String.t(), keyword() | map()) :: map()
```

Encodes an `fs/read_text_file` request from agent to client.

# `encode_file_read_response`

```elixir
@spec encode_file_read_response(integer() | String.t() | nil, String.t()) :: map()
```

Encodes a response to a `fs/read_text_file` request from the agent.

# `encode_file_write_request`

```elixir
@spec encode_file_write_request(String.t(), String.t(), String.t()) :: map()
```

Encodes an `fs/write_text_file` request from agent to client.

# `encode_file_write_response`

```elixir
@spec encode_file_write_response(integer() | String.t() | nil) :: map()
```

Encodes a response to a `fs/write_text_file` request from the agent.

# `encode_initialize`

```elixir
@spec encode_initialize(map(), map() | nil, pos_integer()) :: map()
```

Encodes an `initialize` request.

## Parameters

- `client_info` — `%{"name" => ..., "version" => ...}`
- `capabilities` — client capabilities map (optional)
- `protocol_version` — integer (default: 1)

# `encode_initialize_response`

```elixir
@spec encode_initialize_response(
  integer() | String.t(),
  map(),
  map() | nil,
  [map()] | nil,
  pos_integer()
) :: map()
```

Encodes an agent `initialize` response.

# `encode_logout`

```elixir
@spec encode_logout() :: map()
```

Encodes a `logout` request. Stabilized in ACP spec May 21, 2026.

# `encode_permission_request`

```elixir
@spec encode_permission_request(String.t(), map(), [map()]) :: map()
```

Encodes a `session/request_permission` request from agent to client.

Each option's `kind` must be one of the spec enums
`allow_once`, `allow_always`, `reject_once`, `reject_always`
per https://agentclientprotocol.com/protocol/tool-calls. Non-spec
values raise `ArgumentError` — a client receiving an unrecognized
kind cannot render the correct UI affordance.

# `encode_permission_response`

```elixir
@spec encode_permission_response(integer() | String.t() | nil, map()) :: map()
```

Encodes a response to a `session/request_permission` request from the agent.

# `encode_plan`

```elixir
@spec encode_plan(String.t(), [map()]) :: map()
```

Encodes an ACP `plan` update notification.

# `encode_prompt_response`

```elixir
@spec encode_prompt_response(integer() | String.t() | nil, String.t() | map()) ::
  map()
```

Encodes a `session/prompt` response.

# `encode_request_cancelled_error`

```elixir
@spec encode_request_cancelled_error(integer() | String.t() | nil) :: map()
```

Encodes the ACP/JSON-RPC request-cancelled error response.

# `encode_response`

Encodes a JSON-RPC success response.

# `encode_session_cancel`

```elixir
@spec encode_session_cancel(String.t()) :: map()
```

Encodes a `session/cancel` notification (no id field).

# `encode_session_close`

```elixir
@spec encode_session_close(String.t()) :: map()
```

Encodes a `session/close` request. Stabilized in ACP spec April 23, 2026.

# `encode_session_delete`

```elixir
@spec encode_session_delete(String.t()) :: map()
```

Encodes a `session/delete` request. Gated by `sessionCapabilities.delete`
per https://agentclientprotocol.com/protocol/session-list.

# `encode_session_fork`

```elixir
@spec encode_session_fork(String.t(), String.t(), keyword() | map() | [map()] | nil) ::
  map()
```

Encodes an unstable `session/fork` request.

`cwd` is required and must be an absolute path at the client validation
boundary. The request shape matches `session/resume`.

# `encode_session_info_update`

```elixir
@spec encode_session_info_update(String.t(), map()) :: map()
```

Encodes a `session_info_update` notification.

# `encode_session_list`

```elixir
@spec encode_session_list(keyword()) :: map()
```

Encodes a `session/list` request. Stabilized in ACP spec March 9, 2026.

# `encode_session_list_response`

```elixir
@spec encode_session_list_response(
  integer() | String.t() | nil,
  [map()],
  String.t() | nil
) :: map()
```

Encodes a `session/list` response.

# `encode_session_load`

```elixir
@spec encode_session_load(String.t(), String.t(), keyword() | map() | [map()] | nil) ::
  map()
```

Encodes a `session/load` request to load an existing session and replay history.

`cwd` is required by the ACP spec
(https://agentclientprotocol.com/protocol/session-setup) and must be an
absolute path string. Passing `nil` raises `FunctionClauseError`.

# `encode_session_new`

```elixir
@spec encode_session_new(String.t(), keyword() | map() | [map()] | nil) :: map()
```

Encodes a `session/new` request.

`cwd` is required by the ACP spec
(https://agentclientprotocol.com/protocol/session-setup) and must be an
absolute path string. Passing `nil` raises `FunctionClauseError`.

# `encode_session_prompt`

```elixir
@spec encode_session_prompt(String.t(), [map()]) :: map()
```

Encodes a `session/prompt` request.

# `encode_session_response`

```elixir
@spec encode_session_response(integer() | String.t() | nil, String.t() | map() | nil) ::
  map()
```

Encodes a `session/new`, `session/load`, or similar session ID response.

# `encode_session_resume`

```elixir
@spec encode_session_resume(String.t(), String.t(), keyword() | map() | [map()] | nil) ::
  map()
```

Encodes a `session/resume` request. Stabilized in ACP spec April 22, 2026.

`cwd` is required (same shape as `session/load` per
https://agentclientprotocol.com/protocol/session-list). Passing `nil`
raises `FunctionClauseError`.

# `encode_session_set_config_option`

```elixir
@spec encode_session_set_config_option(String.t(), String.t(), any()) :: map()
```

Encodes a `session/set_config_option` request.

# `encode_session_set_mode`

```elixir
@spec encode_session_set_mode(String.t(), String.t()) :: map()
```

Encodes a `session/set_mode` request.

# `encode_session_set_model`

```elixir
@spec encode_session_set_model(String.t(), String.t()) :: map()
```

Encodes a `session/set_model` request.

# `encode_session_update`

```elixir
@spec encode_session_update(String.t(), map()) :: map()
```

Encodes a stable ACP `session/update` notification.

# `encode_terminal_request`

```elixir
@spec encode_terminal_request(String.t(), String.t(), map()) :: map()
```

Encodes a stable `terminal/*` request from agent to client.

# `encode_tool_call`

```elixir
@spec encode_tool_call(String.t(), map()) :: map()
```

Encodes a `tool_call` update notification.

# `encode_tool_call_update`

```elixir
@spec encode_tool_call_update(String.t(), map()) :: map()
```

Encodes a `tool_call_update` notification.

# `encode_usage_update`

```elixir
@spec encode_usage_update(
  String.t(),
  non_neg_integer(),
  non_neg_integer(),
  map() | nil
) :: map()
```

Encodes a `usage_update` notification.

# `encode_user_message_chunk`

```elixir
@spec encode_user_message_chunk(String.t(), String.t() | map(), keyword() | map()) ::
  map()
```

Encodes a `user_message_chunk` update notification.

# `generate_id`

Generates a unique request ID.

# `parse_message`

```elixir
@spec parse_message(String.t() | map()) ::
  {:request, String.t(), map(), integer() | String.t() | nil}
  | {:notification, String.t(), map()}
  | {:result, any(), integer() | String.t() | nil}
  | {:error, map(), integer() | String.t() | nil}
  | {:error, :invalid_message}
```

Parses a raw ACP JSON-RPC message with structural validation.

---

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