-253
claudeio/TODO.md
-253
claudeio/TODO.md
···-Hooks allow users to intercept and modify Claude's behavior at specific points during execution. The Python SDK supports several hook events that are not yet implemented in the OCaml library.-4. **Update SDK control protocol** to support hook registration via `SDKControlInitializeRequest`-MCP servers allow Claude to interact with external services and tools. The Python SDK supports multiple MCP server configurations.
+1
-1
claudeio/claude.opam
+1
-1
claudeio/claude.opam
+1
-1
claudeio/dune-project
+1
-1
claudeio/dune-project
+1
claudeio/lib/claude.ml
+1
claudeio/lib/claude.ml
+3
claudeio/lib/claude.mli
+3
claudeio/lib/claude.mli
···
+184
-104
claudeio/lib/client.ml
+184
-104
claudeio/lib/client.ml
·········(* Convert permission result to CLI format: {"behavior": "allow", "updatedInput": ...} or {"behavior": "deny", "message": ...} *)·········+"hookCallbackIds", Jsont.Array (List.map (fun id -> json_string id) callback_ids, Jsont.Meta.none);···············
+215
-130
claudeio/lib/content_block.ml
+215
-130
claudeio/lib/content_block.ml
···············
+102
-56
claudeio/lib/content_block.mli
+102
-56
claudeio/lib/content_block.mli
··················
+38
-18
claudeio/lib/control.ml
+38
-18
claudeio/lib/control.ml
···
+16
-7
claudeio/lib/control.mli
+16
-7
claudeio/lib/control.mli
······
+1
-1
claudeio/lib/dune
+1
-1
claudeio/lib/dune
+478
-201
claudeio/lib/hooks.ml
+478
-201
claudeio/lib/hooks.ml
·········+|> Jsont.Object.opt_mem "permissionDecision" permission_decision_jsont ~enc:(fun o -> o.permission_decision)+|> Jsont.Object.opt_mem "permissionDecisionReason" Jsont.string ~enc:(fun o -> o.permission_decision_reason)+let continue ?(unknown = Output_unknown.empty) () = { decision = None; reason = None; unknown }+let block ?reason ?(unknown = Output_unknown.empty) () = { decision = Some Block; reason; unknown }······+Jsont.Json.mem (Jsont.Json.name "callbacks") (Jsont.Json.list []); (* Placeholder, filled by client *)
+228
-64
claudeio/lib/hooks.mli
+228
-64
claudeio/lib/hooks.mli
·········+val allow : ?reason:string -> ?updated_input:Jsont.json -> ?unknown:Output_unknown.t -> unit -> output+val block : ?reason:string -> ?additional_context:string -> ?unknown:Output_unknown.t -> unit -> output······-val continue : ?system_message:string -> ?hook_specific_output:Ezjsonm.value -> unit -> result+val continue : ?system_message:string -> ?hook_specific_output:Jsont.json -> ?unknown:Result_unknown.t -> unit -> result+val block : ?system_message:string -> ?hook_specific_output:Jsont.json -> ?unknown:Result_unknown.t -> unit -> result···
+55
claudeio/lib/incoming.ml
+55
claudeio/lib/incoming.ml
···+| Control_response resp -> Format.fprintf fmt "@[<2>ControlResponse@ %a@]" Sdk_control.pp (Sdk_control.Response resp)
+22
claudeio/lib/incoming.mli
+22
claudeio/lib/incoming.mli
···
-85
claudeio/lib/json_utils.ml
-85
claudeio/lib/json_utils.ml
···
-51
claudeio/lib/json_utils.mli
-51
claudeio/lib/json_utils.mli
···
+396
-179
claudeio/lib/message.ml
+396
-179
claudeio/lib/message.ml
·········+(Jsont.Json.name "content", Jsont.Array (List.map Content_block.to_json t.content, Jsont.Meta.none));+| Some err -> (Jsont.Json.name "error", Jsont.String (error_to_string err, Jsont.Meta.none)) :: msg_fields·········+| Some n -> (Jsont.Json.name "input_tokens", Jsont.Number (float_of_int n, Jsont.Meta.none)) :: fields+| Some n -> (Jsont.Json.name "output_tokens", Jsont.Number (float_of_int n, Jsont.Meta.none)) :: fields+| Some n -> (Jsont.Json.name "total_tokens", Jsont.Number (float_of_int n, Jsont.Meta.none)) :: fields+| Some n -> (Jsont.Json.name "cache_creation_input_tokens", Jsont.Number (float_of_int n, Jsont.Meta.none)) :: fields+| Some n -> (Jsont.Json.name "cache_read_input_tokens", Jsont.Number (float_of_int n, Jsont.Meta.none)) :: fields············+(Jsont.Json.name "duration_api_ms", Jsont.Number (float_of_int t.duration_api_ms, Jsont.Meta.none));+| Some cost -> (Jsont.Json.name "total_cost_usd", Jsont.Number (cost, Jsont.Meta.none)) :: fields······+let data = System.Data.of_assoc [(("session_id", Jsont.String (session_id, Jsont.Meta.none)))] in······
+171
-110
claudeio/lib/message.mli
+171
-110
claudeio/lib/message.mli
······val create_mixed : text:string option -> tool_results:(string * string * bool option) list -> t(** [as_text t] returns the text content if the message is a simple string, None otherwise. *)(** [get_blocks t] returns the content blocks, or a single text block if it's a string message. *)············(** [effective_input_tokens t] returns input tokens minus cached tokens, or 0 if not available. *)············val user_with_tool_result : tool_use_id:string -> content:string -> ?is_error:bool -> unit -> tval assistant : content:Content_block.t list -> model:string -> ?error:Assistant.error -> unit -> t···
+27
claudeio/lib/model.ml
+27
claudeio/lib/model.ml
···
+36
claudeio/lib/model.mli
+36
claudeio/lib/model.mli
···
+82
-99
claudeio/lib/options.ml
+82
-99
claudeio/lib/options.ml
·····················+|> Jsont.Object.mem "allowed_tools" (Jsont.list Jsont.string) ~enc:allowed_tools ~dec_absent:[]+|> Jsont.Object.mem "disallowed_tools" (Jsont.list Jsont.string) ~enc:disallowed_tools ~dec_absent:[]
+10
-5
claudeio/lib/options.mli
+10
-5
claudeio/lib/options.mli
···············
+192
-168
claudeio/lib/permissions.ml
+192
-168
claudeio/lib/permissions.ml
··················+let create ~update_type ?rules ?behavior ?mode ?directories ?destination ?(unknown = Unknown.empty) () =······
+127
-106
claudeio/lib/permissions.mli
+127
-106
claudeio/lib/permissions.mli
·········+val allow : ?updated_input:Jsont.json -> ?updated_permissions:Update.t list -> ?unknown:Unknown.t -> unit -> t
+288
-256
claudeio/lib/sdk_control.ml
+288
-256
claudeio/lib/sdk_control.ml
······+let permission ~tool_name ~input ?permission_suggestions ?blocked_path ?(unknown = Unknown.empty) () =+let make tool_name input permission_suggestions blocked_path (unknown : Unknown.t) : permission =+|> Jsont.Object.opt_mem "permission_suggestions" (Jsont.list Permissions.Update.jsont) ~enc:(fun (r : permission) -> r.permission_suggestions)+|> Jsont.Object.opt_mem "blocked_path" Jsont.string ~enc:(fun (r : permission) -> r.blocked_path)+let make hooks (unknown : Unknown.t) : initialize = { subtype = `Initialize; hooks; unknown } in+let make mode (unknown : Unknown.t) : set_permission_mode = { subtype = `Set_permission_mode; mode; unknown } in+|> Jsont.Object.mem "mode" Permissions.Mode.jsont ~enc:(fun (r : set_permission_mode) -> r.mode)+|> Jsont.Object.keep_unknown Jsont.json_mems ~enc:(fun (r : set_permission_mode) -> r.unknown)+|> Jsont.Object.mem "callback_id" Jsont.string ~enc:(fun (r : hook_callback) -> r.callback_id)+|> Jsont.Object.opt_mem "tool_use_id" Jsont.string ~enc:(fun (r : hook_callback) -> r.tool_use_id)+let make model (unknown : Unknown.t) : set_model = { subtype = `Set_model; model; unknown } in+let case_interrupt = Jsont.Object.Case.map "interrupt" interrupt_jsont ~dec:(fun v -> Interrupt v) in+let case_permission = Jsont.Object.Case.map "can_use_tool" permission_jsont ~dec:(fun v -> Permission v) in+let case_initialize = Jsont.Object.Case.map "initialize" initialize_jsont ~dec:(fun v -> Initialize v) in+let case_set_permission_mode = Jsont.Object.Case.map "set_permission_mode" set_permission_mode_jsont ~dec:(fun v -> Set_permission_mode v) in+let case_hook_callback = Jsont.Object.Case.map "hook_callback" hook_callback_jsont ~dec:(fun v -> Hook_callback v) in+let case_mcp_message = Jsont.Object.Case.map "mcp_message" mcp_message_jsont ~dec:(fun v -> Mcp_message v) in+let case_set_model = Jsont.Object.Case.map "set_model" set_model_jsont ~dec:(fun v -> Set_model v) in+let case_get_server_info = Jsont.Object.Case.map "get_server_info" get_server_info_jsont ~dec:(fun v -> Get_server_info v) in······+|> Jsont.Object.mem "request_id" Jsont.string ~enc:(fun (r : control_request) -> r.request_id)+let case_request = Jsont.Object.Case.map "control_request" control_request_jsont ~dec:(fun v -> Request v) in+let case_response = Jsont.Object.Case.map "control_response" control_response_jsont ~dec:(fun v -> Response v) in···+|> Jsont.Object.mem "capabilities" (Jsont.list Jsont.string) ~enc:(fun (r : t) -> r.capabilities) ~dec_absent:[]+|> Jsont.Object.mem "commands" (Jsont.list Jsont.string) ~enc:(fun (r : t) -> r.commands) ~dec_absent:[]+|> Jsont.Object.mem "outputStyles" (Jsont.list Jsont.string) ~enc:(fun (r : t) -> r.output_styles) ~dec_absent:[]
+117
-82
claudeio/lib/sdk_control.mli
+117
-82
claudeio/lib/sdk_control.mli
·········+(** [hook_callback ~callback_id ~input ?tool_use_id ?unknown ()] creates a hook callback request. *)···+val create_request : request_id:string -> request:Request.t -> ?unknown:Unknown.t -> unit -> t·········+(** [create ~version ~capabilities ~commands ~output_styles ?unknown ()] creates server info. *)···
+49
claudeio/lib/structured_output.ml
+49
claudeio/lib/structured_output.ml
···
+171
claudeio/lib/structured_output.mli
+171
claudeio/lib/structured_output.mli
···
+15
-9
claudeio/lib/transport.ml
+15
-9
claudeio/lib/transport.ml
·········
+2
-2
claudeio/lib/transport.mli
+2
-2
claudeio/lib/transport.mli
···
+165
claudeio/test/advanced_config_demo.ml
+165
claudeio/test/advanced_config_demo.ml
···
+16
-5
claudeio/test/dune
+16
-5
claudeio/test/dune
············
+91
claudeio/test/dynamic_control_demo.ml
+91
claudeio/test/dynamic_control_demo.ml
···
+2
-2
claudeio/test/hooks_example.ml
+2
-2
claudeio/test/hooks_example.ml
···
+27
-22
claudeio/test/permission_demo.ml
+27
-22
claudeio/test/permission_demo.ml
······-Claude.Permissions.Result.deny ~message:(Printf.sprintf "User denied access to %s" tool_name) ~interrupt:false+Claude.Permissions.Result.deny ~message:(Printf.sprintf "User denied access to %s" tool_name) ~interrupt:false ()
+1
-1
claudeio/test/simple_permission_test.ml
+1
-1
claudeio/test/simple_permission_test.ml
···
+29
-17
claudeio/test/simulated_permissions.ml
+29
-17
claudeio/test/simulated_permissions.ml
···············
+172
claudeio/test/structured_output_demo.ml
+172
claudeio/test/structured_output_demo.ml
···+let language = Test_json_utils.get_string output "primary_language" |> Option.value ~default:"unknown" in+let complexity = Test_json_utils.get_string output "complexity_rating" |> Option.value ~default:"unknown" in
+72
claudeio/test/structured_output_simple.ml
+72
claudeio/test/structured_output_simple.ml
···
+78
claudeio/test/test_incoming.ml
+78
claudeio/test/test_incoming.ml
···+let json_str = {|{"type":"assistant","model":"claude-sonnet-4","content":[{"type":"text","text":"Hi"}]}|} in+let json_str = {|{"type":"control_response","response":{"subtype":"success","request_id":"test-req-1"}}|} in+let json_str = {|{"type":"control_response","response":{"subtype":"error","request_id":"test-req-2","error":"Something went wrong"}}|} in
+41
claudeio/test/test_json_utils.ml
+41
claudeio/test/test_json_utils.ml
···