(** SDK Control Protocol for Claude. This module defines the typed SDK control protocol for bidirectional communication between the SDK and the Claude CLI. It handles: - Permission requests (tool usage authorization) - Hook callbacks (intercepting and modifying tool execution) - Dynamic control (changing settings mid-conversation) - Server introspection (querying capabilities) {2 Protocol Overview} The SDK control protocol is a JSON-based request/response protocol that runs alongside the main message stream. It enables: 1. {b Callbacks}: Claude asks the SDK for permission or hook execution 2. {b Control}: SDK changes Claude's behavior dynamically 3. {b Introspection}: SDK queries server metadata {2 Request/Response Flow} {v SDK Claude CLI | | |-- Initialize (with hooks) --> | |<-- Permission Request --------| (for tool usage) |-- Allow/Deny Response ------> | | | |<-- Hook Callback -------------| (pre/post tool) |-- Hook Result -------------> | | | |-- Set Model ---------------> | (dynamic control) |<-- Success Response ----------| | | |-- Get Server Info ----------> | |<-- Server Info Response ------| v} {2 Usage} Most users won't interact with this module directly. The {!Client} module handles the protocol automatically. However, this module is exposed for: - Understanding the control protocol - Implementing custom control logic - Debugging control message flow - Advanced SDK extensions {2 Dynamic Control Examples} See {!Client.set_permission_mode}, {!Client.set_model}, and {!Client.get_server_info} for high-level APIs that use this protocol. *) open Ezjsonm (** The log source for SDK control operations *) val src : Logs.Src.t (** {1 Request Types} *) module Request : sig (** SDK control request types. *) type interrupt = { subtype : [`Interrupt]; } (** Interrupt request to stop execution. *) type permission = { subtype : [`Can_use_tool]; tool_name : string; input : value; permission_suggestions : Permissions.Update.t list option; blocked_path : string option; } (** Permission request for tool usage. *) type initialize = { subtype : [`Initialize]; hooks : (string * value) list option; (* Hook event to configuration *) } (** Initialize request with optional hook configuration. *) type set_permission_mode = { subtype : [`Set_permission_mode]; mode : Permissions.Mode.t; } (** Request to change permission mode. *) type hook_callback = { subtype : [`Hook_callback]; callback_id : string; input : value; tool_use_id : string option; } (** Hook callback request. *) type mcp_message = { subtype : [`Mcp_message]; server_name : string; message : value; } (** MCP server message request. *) type set_model = { subtype : [`Set_model]; model : string; } (** Request to change the AI model. *) type get_server_info = { subtype : [`Get_server_info]; } (** Request to get server information. *) type t = | Interrupt of interrupt | Permission of permission | Initialize of initialize | Set_permission_mode of set_permission_mode | Hook_callback of hook_callback | Mcp_message of mcp_message | Set_model of set_model | Get_server_info of get_server_info (** The type of SDK control requests. *) val interrupt : unit -> t (** [interrupt ()] creates an interrupt request. *) val permission : tool_name:string -> input:value -> ?permission_suggestions:Permissions.Update.t list -> ?blocked_path:string -> unit -> t (** [permission ~tool_name ~input ?permission_suggestions ?blocked_path ()] creates a permission request. *) val initialize : ?hooks:(string * value) list -> unit -> t (** [initialize ?hooks ()] creates an initialize request. *) val set_permission_mode : mode:Permissions.Mode.t -> t (** [set_permission_mode ~mode] creates a permission mode change request. *) val hook_callback : callback_id:string -> input:value -> ?tool_use_id:string -> unit -> t (** [hook_callback ~callback_id ~input ?tool_use_id ()] creates a hook callback request. *) val mcp_message : server_name:string -> message:value -> t (** [mcp_message ~server_name ~message] creates an MCP message request. *) val set_model : model:string -> t (** [set_model ~model] creates a model change request. *) val get_server_info : unit -> t (** [get_server_info ()] creates a server info request. *) val to_json : t -> value (** [to_json t] converts a request to JSON. *) val of_json : value -> t (** [of_json json] parses a request from JSON. @raise Invalid_argument if the JSON is not a valid request. *) val pp : Format.formatter -> t -> unit (** [pp fmt t] pretty-prints the request. *) end (** {1 Response Types} *) module Response : sig (** SDK control response types. *) type success = { subtype : [`Success]; request_id : string; response : value option; } (** Successful response. *) type error = { subtype : [`Error]; request_id : string; error : string; } (** Error response. *) type t = | Success of success | Error of error (** The type of SDK control responses. *) val success : request_id:string -> ?response:value -> unit -> t (** [success ~request_id ?response ()] creates a success response. *) val error : request_id:string -> error:string -> t (** [error ~request_id ~error] creates an error response. *) val to_json : t -> value (** [to_json t] converts a response to JSON. *) val of_json : value -> t (** [of_json json] parses a response from JSON. @raise Invalid_argument if the JSON is not a valid response. *) val pp : Format.formatter -> t -> unit (** [pp fmt t] pretty-prints the response. *) end (** {1 Control Messages} *) type control_request = { type_ : [`Control_request]; request_id : string; request : Request.t; } (** Control request message. *) type control_response = { type_ : [`Control_response]; response : Response.t; } (** Control response message. *) type t = | Request of control_request | Response of control_response (** The type of SDK control messages. *) val create_request : request_id:string -> request:Request.t -> t (** [create_request ~request_id ~request] creates a control request message. *) val create_response : response:Response.t -> t (** [create_response ~response] creates a control response message. *) val to_json : t -> value (** [to_json t] converts a control message to JSON. *) val of_json : value -> t (** [of_json json] parses a control message from JSON. @raise Invalid_argument if the JSON is not a valid control message. *) val pp : Format.formatter -> t -> unit (** [pp fmt t] pretty-prints the control message. *) (** {1 Logging} *) val log_request : Request.t -> unit (** [log_request req] logs an SDK control request. *) val log_response : Response.t -> unit (** [log_response resp] logs an SDK control response. *) (** {1 Server Information} Server information provides metadata about the Claude CLI server, including version, capabilities, available commands, and output styles. {2 Use Cases} - Feature detection: Check if specific capabilities are available - Version compatibility: Ensure minimum version requirements - Debugging: Log server information for troubleshooting - Dynamic adaptation: Adjust SDK behavior based on capabilities {2 Example} {[ let info = Client.get_server_info client in Printf.printf "Claude CLI version: %s\n" (Server_info.version info); if List.mem "structured-output" (Server_info.capabilities info) then Printf.printf "Structured output is supported\n" else Printf.printf "Structured output not available\n"; ]} *) module Server_info : sig (** Server information and capabilities. *) type t = { version : string; (** Server version string (e.g., "2.0.0") *) capabilities : string list; (** Available server capabilities (e.g., "hooks", "structured-output") *) commands : string list; (** Available CLI commands *) output_styles : string list; (** Supported output formats (e.g., "json", "stream-json") *) } (** Server metadata and capabilities. This information is useful for feature detection and debugging. *) val create : version:string -> capabilities:string list -> commands:string list -> output_styles:string list -> t (** [create ~version ~capabilities ~commands ~output_styles] creates server info. *) val version : t -> string (** [version t] returns the server version. *) val capabilities : t -> string list (** [capabilities t] returns the server capabilities. *) val commands : t -> string list (** [commands t] returns available commands. *) val output_styles : t -> string list (** [output_styles t] returns available output styles. *) val of_json : value -> t (** [of_json json] parses server info from JSON. @raise Invalid_argument if the JSON is not valid server info. *) val to_json : t -> value (** [to_json t] converts server info to JSON. *) val pp : Format.formatter -> t -> unit (** [pp fmt t] pretty-prints the server info. *) end