# `ClaudeAgentSDK.ControlProtocol.Protocol`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L1)

Control protocol message encoding and decoding.

Handles bidirectional communication with Claude CLI via control messages:
- Initialize requests with hooks configuration
- Hook callback requests/responses
- Control requests/responses

Messages are exchanged as JSON over stdin/stdout.

## Message Types

### SDK → CLI
- `control_request` with `initialize` subtype
- `control_response` for hook callbacks

### CLI → SDK
- `control_request` with `hook_callback` subtype
- `control_response` for initialize

See: https://docs.anthropic.com/en/docs/claude-code/sdk

# `message_type`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L33)

```elixir
@type message_type() ::
  :control_request
  | :control_response
  | :control_cancel_request
  | :sdk_message
  | :stream_event
```

Message type classifier.

# `request_id`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L28)

```elixir
@type request_id() :: String.t()
```

Request ID for tracking control protocol requests.

# `control_message?`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L356)

```elixir
@spec control_message?(map()) :: boolean()
```

Checks if a message is a control protocol message.

## Parameters

- `message` - Decoded message map

## Returns

`true` if control message, `false` otherwise

## Examples

    iex> Protocol.control_message?(%{"type" => "control_request"})
    true

    iex> Protocol.control_message?(%{"type" => "assistant"})
    false

# `decode_message`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L301)

```elixir
@spec decode_message(String.t()) :: {:ok, {message_type(), map()}} | {:error, term()}
```

Decodes a message from CLI.

Parses JSON and classifies message type.

## Parameters

- `json_string` - JSON message from CLI

## Returns

- `{:ok, {message_type, data}}` - Successfully decoded
- `{:error, reason}` - Failed to decode

## Examples

    iex> json = ~s({"type":"control_request","request_id":"req_1","request":{}})
    iex> {:ok, {type, _data}} = Protocol.decode_message(json)
    iex> type
    :control_request

# `decode_set_model_response`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L237)

```elixir
@spec decode_set_model_response(map()) :: {:ok, String.t()} | {:error, term()}
```

Decodes a set_model control response.

# `encode_hook_response`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L207)

```elixir
@spec encode_hook_response(request_id(), map() | String.t(), :success | :error) ::
  String.t()
```

Encodes a hook callback response.

Sends the result of a hook callback execution back to CLI.

## Parameters

- `request_id` - Request ID from CLI's hook_callback request
- `output_or_error` - Hook output map or error string
- `status` - `:success` or `:error`

## Returns

JSON string ready to send to CLI

## Examples

    # Success
    output = %{hookSpecificOutput: %{permissionDecision: "allow"}}
    json = Protocol.encode_hook_response("req_123", output, :success)

    # Error
    json = Protocol.encode_hook_response("req_456", "Timeout", :error)

# `encode_initialize_request`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L72)

```elixir
@spec encode_initialize_request(map() | nil, map() | nil, request_id() | nil) ::
  {request_id(), String.t()}
```

Encodes an initialize request with hooks configuration and SDK MCP servers.

Sends hooks configuration and SDK MCP server info to CLI during initialization
so it knows which callbacks to invoke and which SDK servers are available.

## Parameters

- `hooks_config` - Hooks configuration map (from build_hooks_config)
- `sdk_mcp_servers` - Map of server_name => server_info for SDK servers (optional)
- `request_id` - Optional request ID (generated if nil)

## Returns

`{request_id, json_string}` tuple

## Examples

    hooks = %{
      "PreToolUse" => [
        %{"matcher" => "Bash", "hookCallbackIds" => ["hook_0"]}
      ]
    }

    sdk_servers = %{
      "math-tools" => %{"name" => "math-tools", "version" => "1.0.0"}
    }

    {id, json} = Protocol.encode_initialize_request(hooks, sdk_servers, nil)

# `encode_interrupt_request`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L146)

```elixir
@spec encode_interrupt_request(request_id() | nil) :: {request_id(), String.t()}
```

Encodes an interrupt control request.

# `encode_rewind_files_request`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L126)

```elixir
@spec encode_rewind_files_request(String.t(), request_id() | nil) ::
  {request_id(), String.t()}
```

Encodes a rewind_files control request.

Returns `{request_id, json}`.

# `encode_set_model_request`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L104)

```elixir
@spec encode_set_model_request(String.t(), request_id() | nil) ::
  {request_id(), String.t()}
```

Encodes a set_model control request.

Returns `{request_id, json}`.

# `encode_set_permission_mode_request`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L167)

```elixir
@spec encode_set_permission_mode_request(String.t(), request_id() | nil) ::
  {request_id(), String.t()}
```

Encodes a set_permission_mode control request.

Returns `{request_id, json}`.

# `generate_request_id`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.9.2/lib/claude_agent_sdk/control_protocol/protocol.ex#L330)

```elixir
@spec generate_request_id() :: request_id()
```

Generates a unique request ID.

Format: `req_{counter}_{random_hex}`

## Examples

    iex> id = Protocol.generate_request_id()
    iex> String.starts_with?(id, "req_")
    true

---

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