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/client.mli

Run mdx on lib/client.mli so the six {[ ... ]} odoc blocks now
type-check.

Several drift fixes against the current API:
- `receive_all` returns `Claude.Response.t list`, not
`Claude.Message.t list`; the basic example matches against
Response.Text and uses Response.Text.content.
- `Claude.Message.Assistant.text` doesn't exist; the only call I
needed was `combined_text`.
- `Claude.Client.set_model` and `Claude.Options.with_model` both
take `Claude.Model.t`, not string -- went through `Model.of_string`.
- `Claude.Server_info` is the right path (the previous text used
`Claude.Control.Server_info`).

Each example wrapped in a named function (`with_handler`,
`with_adaptive_permissions`, `with_model_switch`, `print_server_info`,
`run`) so the spawn-Claude-CLI side effect doesn't fire at mdx test
time, and dropped trailing `ignore (...) : Response.t list` lines in
favour of `let messages = ... in Fmt.pr "%d events@." (List.length
messages)` so the example shows what the receive_all output looks
like.

+72 -58
+70 -56
lib/client.mli
··· 12 12 {2 Basic Usage} 13 13 14 14 {[ 15 - Eio.Switch.run @@ fun sw -> 16 - let client = Client.v ~sw ~process_mgr ~clock () in 17 - Client.query client "What is 2+2?"; 18 - 19 - let messages = Client.receive_all client in 20 - List.iter 21 - (function 22 - | Message.Assistant msg -> 23 - Printf.printf "Claude: %s\n" (Message.Assistant.text msg) 24 - | _ -> ()) 25 - messages 15 + let run () = 16 + Eio_main.run @@ fun env -> 17 + let process_mgr = Eio.Stdenv.process_mgr env in 18 + let clock = Eio.Stdenv.clock env in 19 + Eio.Switch.run @@ fun sw -> 20 + let client = Claude.Client.v ~sw ~process_mgr ~clock () in 21 + Claude.Client.query client "What is 2+2?"; 22 + let messages = Claude.Client.receive_all client in 23 + List.iter 24 + (function 25 + | Claude.Response.Text t -> 26 + Fmt.pr "Claude: %s@." (Claude.Response.Text.content t) 27 + | _ -> ()) 28 + messages 26 29 ]} 27 30 28 31 {2 Features} ··· 106 109 107 110 Example: 108 111 {[ 109 - Client.respond_to_tools client 110 - [ 111 - ("tool_use_123", Json.Value.string "Success", None); 112 - ("tool_use_456", Json.Value.string "Error occurred", Some true); 113 - ] 112 + let respond client = 113 + Claude.Client.respond_to_tools client 114 + [ 115 + ("tool_use_123", Json.Value.string "Success", None); 116 + ("tool_use_456", Json.Value.string "Error occurred", Some true); 117 + ] 114 118 ]} *) 115 119 116 120 val clear_tool_response_tracking : t -> unit ··· 131 135 132 136 Example: 133 137 {[ 134 - let my_handler = 135 - object 136 - inherit Claude.Handler.default 137 - method! on_text t = print_endline (Response.Text.content t) 138 + let with_handler client = 139 + let my_handler = 140 + object 141 + inherit Claude.Handler.default 142 + method! on_text t = print_endline (Claude.Response.Text.content t) 138 143 139 - method! on_complete c = 140 - Printf.printf "Cost: $%.4f\n" 141 - (Option.value ~default:0.0 (Response.Complete.total_cost_usd c)) 142 - end 143 - in 144 - Client.query client "Hello"; 145 - Client.run client ~handler:my_handler 144 + method! on_complete c = 145 + Fmt.pr "Cost: $%.4f@." 146 + (Option.value ~default:0.0 147 + (Claude.Response.Complete.total_cost_usd c)) 148 + end 149 + in 150 + Claude.Client.query client "Hello"; 151 + Claude.Client.run client ~handler:my_handler 146 152 ]} *) 147 153 148 154 val receive : t -> Response.t Seq.t ··· 186 192 {2 Example: Adaptive Permission Control} 187 193 188 194 {[ 189 - (* Start with strict permissions *) 190 - let client = Client.v ~sw ~process_mgr ~clock 191 - ~options:(Options.default 192 - |> Options.with_permission_mode Permissions.Mode.Default) () 195 + let with_adaptive_permissions ~sw ~process_mgr ~clock = 196 + (* Start with strict permissions. *) 197 + let client = 198 + Claude.Client.v ~sw ~process_mgr ~clock 199 + ~options: 200 + Claude.Options.( 201 + default |> with_permission_mode Claude.Permissions.Mode.Default) 202 + () 193 203 in 194 - 195 - Client.query client "Analyze this code"; 196 - let _ = Client.receive_all client in 197 - 198 - (* User approves, switch to auto-accept edits *) 199 - Client.set_permission_mode client Permissions.Mode.Accept_edits; 200 - 201 - Client.query client "Now refactor it"; 202 - let _ = Client.receive_all client in 204 + Claude.Client.query client "Analyze this code"; 205 + let analysis = Claude.Client.receive_all client in 206 + Fmt.pr "analysis: %d events@." (List.length analysis); 207 + (* User approves, switch to auto-accept edits. *) 208 + Claude.Client.set_permission_mode client 209 + Claude.Permissions.Mode.Accept_edits; 210 + Claude.Client.query client "Now refactor it"; 211 + let refactor = Claude.Client.receive_all client in 212 + Fmt.pr "refactor: %d events@." (List.length refactor) 203 213 ]} 204 214 205 215 {2 Example: Model Switching for Efficiency} 206 216 207 217 {[ 208 - (* Use powerful model for complex analysis *) 209 - let client = Client.v ~sw ~process_mgr ~clock 210 - ~options:(Options.default |> Options.with_model "claude-sonnet-4-5") () 218 + let with_model_switch ~sw ~process_mgr ~clock = 219 + let sonnet = Claude.Model.of_string "claude-sonnet-4-5" in 220 + let haiku = Claude.Model.of_string "claude-haiku-4" in 221 + (* Use powerful model for complex analysis. *) 222 + let client = 223 + Claude.Client.v ~sw ~process_mgr ~clock 224 + ~options:Claude.Options.(default |> with_model sonnet) () 211 225 in 212 - 213 - Client.query client "Design a new architecture for this system"; 214 - let _ = Client.receive_all client in 215 - 216 - (* Switch to faster model for simple tasks *) 217 - Client.set_model client "claude-haiku-4"; 218 - 219 - Client.query client "Now write a README"; 220 - let _ = Client.receive_all client in 226 + Claude.Client.query client "Design a new architecture for this system"; 227 + let design = Claude.Client.receive_all client in 228 + Fmt.pr "design: %d events@." (List.length design); 229 + (* Switch to faster model for simple tasks. *) 230 + Claude.Client.set_model client haiku; 231 + Claude.Client.query client "Now write a README"; 232 + let readme = Claude.Client.receive_all client in 233 + Fmt.pr "readme: %d events@." (List.length readme) 221 234 ]} 222 235 223 236 {2 Example: Server Introspection} 224 237 225 238 {[ 226 - let info = Client.server_info client in 227 - Printf.printf "Claude CLI version: %s\n" (Control.Server_info.version info); 228 - Printf.printf "Capabilities: %s\n" 229 - (String.concat ", " (Control.Server_info.capabilities info)) 239 + let print_server_info client = 240 + let info = Claude.Client.server_info client in 241 + Fmt.pr "Claude CLI version: %s@." (Claude.Server_info.version info); 242 + Fmt.pr "Capabilities: %s@." 243 + (String.concat ", " (Claude.Server_info.capabilities info)) 230 244 ]} *) 231 245 232 246 val set_permission_mode : t -> Permissions.Mode.t -> unit
+2 -2
lib/dune
··· 4 4 (libraries eio eio_main fmt logs nox-json)) 5 5 6 6 (mdx 7 - (files mcp_server.mli) 8 - (libraries claude)) 7 + (files mcp_server.mli client.mli) 8 + (libraries claude nox-json fmt eio eio.core eio.unix eio_main))