OCaml client library for Claude Code
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

ocaml-claude: enable MDX on lib/claude.mli, trim to one Quick Start

The top-level claude.mli had eight {[ ... ]} blocks doing a tour of
every submodule -- Handler, sequence iteration, Tool Permissions,
Permission Callbacks, Hooks, Error handling, Logging, MCP. Each was
its own deeply-nested workflow that did not copy-paste cleanly.

Trimmed to one Quick Start showing the canonical client-spawn +
handler dispatch flow, and replaced each detail tour with a
prose pointer (\"see {!Handler} for response handling, ...\"). The
focused per-module .mli's (handler.mli, hooks.mli, mcp_server.mli,
etc.) still document each piece individually.

+9 -140
+9 -140
lib/claude.mli
··· 40 40 {1 Quick Start} 41 41 42 42 {[ 43 - open Eio.Std 44 - 45 - let () = 43 + let run () = 46 44 Eio_main.run @@ fun env -> 47 - Switch.run @@ fun sw -> 48 - let client = 49 - Claude.Client.v ~sw ~process_mgr:(Eio.Stdenv.process_mgr env) () 50 - in 51 - 45 + let process_mgr = Eio.Stdenv.process_mgr env in 46 + let clock = Eio.Stdenv.clock env in 47 + Eio.Switch.run @@ fun sw -> 48 + let client = Claude.Client.v ~sw ~process_mgr ~clock () in 52 49 Claude.Client.query client "What is 2+2?"; 53 - 54 50 let handler = 55 51 object 56 52 inherit Claude.Handler.default 57 53 method! on_text t = print_endline (Claude.Response.Text.content t) 58 54 end 59 55 in 60 - 61 56 Claude.Client.run client ~handler 62 57 ]} 63 58 ··· 65 60 66 61 The library provides two ways to handle responses: 67 62 68 - {2 Object-Oriented Handler (Recommended)} 69 - 70 - Subclass {!Handler.default} and override only the methods you need: 71 - 72 - {[ 73 - let my_handler = 74 - object 75 - inherit Claude.Handler.default 76 - method! on_text t = print_endline (Claude.Response.Text.content t) 77 - 78 - method! on_tool_use t = 79 - Printf.printf "Tool: %s\n" (Claude.Response.Tool_use.name t) 80 - 81 - method! on_complete c = 82 - Printf.printf "Done! Cost: $%.4f\n" 83 - (Option.value ~default:0.0 84 - (Claude.Response.Complete.total_cost_usd c)) 85 - end 86 - in 87 - 88 - Claude.Client.run client ~handler:my_handler 89 - ]} 90 - 91 - {2 Functional Sequence} 92 - 93 - For more control, use {!Client.receive} to get a lazy sequence: 94 - 95 - {[ 96 - Claude.Client.receive client 97 - |> Seq.iter (function 98 - | Claude.Response.Text t -> print_endline (Claude.Response.Text.content t) 99 - | Claude.Response.Complete c -> Printf.printf "Done!\n" 100 - | _ -> ()) 101 - ]} 102 - 103 - {1 Tool Permissions} 104 - 105 - Control which tools Claude can use: 106 - 107 - {[ 108 - let options = 109 - Claude.Options.default 110 - |> Claude.Options.with_allowed_tools [ "Read"; "Write"; "Bash" ] 111 - |> Claude.Options.with_permission_mode 112 - Claude.Permissions.Mode.Accept_edits 113 - ]} 114 - 115 - {2 Custom Permission Callbacks} 116 - 117 - Implement custom logic for tool approval: 118 - 119 - {[ 120 - let my_callback ctx = 121 - if ctx.Claude.Permissions.tool_name = "Bash" then 122 - Claude.Permissions.Decision.deny ~message:"Bash not allowed" 123 - ~interrupt:false 124 - else Claude.Permissions.Decision.allow () 125 - 126 - let options = 127 - Claude.Options.default 128 - |> Claude.Options.with_permission_callback my_callback 129 - ]} 130 - 131 - {1 Typed Hooks} 132 - 133 - Intercept and control tool execution with fully typed callbacks: 134 - 135 - {[ 136 - let hooks = 137 - Claude.Hooks.empty 138 - |> Claude.Hooks.on_pre_tool_use ~pattern:"Bash" (fun input -> 139 - if 140 - String.is_prefix ~prefix:"rm" 141 - (input.tool_input 142 - |> Claude.Tool_input.string "command" 143 - |> Option.value ~default:"") 144 - then Claude.Hooks.Pre_tool_use.deny ~reason:"Dangerous command" () 145 - else Claude.Hooks.Pre_tool_use.continue ()) 146 - 147 - let options = Claude.Options.default |> Claude.Options.with_hooks hooks 148 - ]} 149 - 150 - {1 Error Handling} 151 - 152 - The library uses a structured exception type {!Error.E} for all errors: 153 - 154 - {[ 155 - try Claude.Client.query client "Hello" 156 - with Claude.Error.E err -> 157 - Printf.eprintf "Error: %s\n" (Claude.Error.to_string err) 158 - ]} 159 - 160 - Error types include: 161 - - {!Error.Cli_not_found}: Claude CLI not found 162 - - {!Error.Process_error}: Process execution failure 163 - - {!Error.Protocol_error}: JSON/protocol parsing error 164 - - {!Error.Timeout}: Operation timed out 165 - - {!Error.Permission_denied}: Tool permission denied 166 - - {!Error.Hook_error}: Hook callback error 167 - 168 - {1 Logging} 169 - 170 - The library uses the Logs library for structured logging. Each module has 171 - its own log source allowing fine-grained control: 172 - 173 - {[ 174 - Logs.Src.set_level Claude.Client.src (Some Logs.Debug); 175 - Logs.Src.set_level Claude.Transport.src (Some Logs.Info) 176 - ]} *) 63 + See {!Handler} for response handling, {!Permissions} for tool approval, 64 + {!Hooks} for typed event interception, {!Error} for structured exception 65 + handling, and {!Client.src} / {!Transport} for per-source log levels. *) 177 66 178 67 (** {1 Core Modules} *) 179 68 ··· 236 125 (Model Context Protocol). Unlike built-in tools which Claude CLI handles 237 126 internally, custom tools are executed by your application. 238 127 239 - {2 Example} 240 - 241 - {[ 242 - let greet = 243 - Claude.Tool.v ~name:"greet" ~description:"Greet a user" 244 - ~input_schema: 245 - (Claude.Tool.schema_object 246 - [ ("name", Claude.Tool.schema_string) ] 247 - ~required:[ "name" ]) 248 - ~handler:(fun args -> 249 - match Claude.Tool_input.string args "name" with 250 - | Some name -> Ok (Claude.Tool.text_result ("Hello, " ^ name ^ "!")) 251 - | None -> Error "Missing name") 252 - 253 - let server = Claude.Mcp_server.v ~name:"my-tools" ~tools:[ greet ] () 254 - 255 - let options = 256 - Claude.Options.default 257 - |> Claude.Options.with_mcp_server ~name:"tools" server 258 - |> Claude.Options.with_allowed_tools [ "mcp__tools__greet" ] 259 - ]} *) 128 + See {!Mcp_server} for the full custom-tool example. *) 260 129 261 130 module Tool = Tool 262 131 (** Custom tool definitions for MCP servers. *)