···11+open Mcp_sdk
22+33+(* Helper module for working with markdown book chapters *)
44+module BookChapter = struct
55+ type t = {
66+ id: string;
77+ title: string;
88+ contents: string;
99+ }
1010+1111+ (* Book chapters as a series of markdown files *)
1212+ let chapters = [
1313+ {
1414+ id = "chapter1";
1515+ title = "# Introduction to OCaml";
1616+ contents = {|
1717+# Introduction to OCaml
1818+1919+OCaml is a general-purpose, multi-paradigm programming language which extends the Caml dialect of ML with object-oriented features.
2020+2121+## Key Features
2222+2323+- **Strong Static Typing**: Catch errors at compile time rather than runtime
2424+- **Type Inference**: No need to annotate every variable with a type
2525+- **Pattern Matching**: Express complex control flow in a clear and concise way
2626+- **Functional Programming**: First-class functions and immutability
2727+- **Module System**: Powerful abstraction capabilities with modules and functors
2828+- **Performance**: Native code compilation with excellent performance characteristics
2929+3030+## History
3131+3232+OCaml was created in 1996 by Xavier Leroy, Jérôme Vouillon, Damien Doligez, and Didier Rémy at INRIA in France. It evolved from the Caml language, which itself was an implementation of ML.
3333+3434+## Why OCaml?
3535+3636+OCaml offers a unique combination of features that make it particularly well-suited for certain domains:
3737+3838+- **Program Correctness**: The strong type system catches many errors at compile time
3939+- **Symbolic Computing**: Excellent for manipulating complex data structures and symbolic expressions
4040+- **Systems Programming**: Can be used for low-level systems programming with high safety guarantees
4141+- **Web Development**: Modern frameworks like Dream make web development straightforward
4242+4343+In the following chapters, we'll explore the language features in depth and learn how to leverage OCaml's strengths for building robust, maintainable software.
4444+|}
4545+ };
4646+ {
4747+ id = "chapter2";
4848+ title = "# Basic Syntax and Types";
4949+ contents = {|
5050+# Basic Syntax and Types
5151+5252+OCaml has a clean, consistent syntax that emphasizes readability and minimizes boilerplate.
5353+5454+## Variables and Basic Types
5555+5656+In OCaml, variables are immutable by default. Once a value is bound to a name, that binding cannot change.
5757+5858+```ocaml
5959+(* Binding a value to a name *)
6060+let x = 42
6161+let greeting = "Hello, World!"
6262+6363+(* OCaml has type inference *)
6464+(* These are equivalent: *)
6565+let x = 42
6666+let x : int = 42
6767+```
6868+6969+## Basic Types
7070+7171+- `int`: Integer numbers
7272+- `float`: Floating-point numbers
7373+- `bool`: Boolean values (`true` or `false`)
7474+- `char`: Single characters
7575+- `string`: Text strings
7676+- `unit`: The empty tuple, written `()`
7777+7878+## Functions
7979+8080+Functions in OCaml are first-class values:
8181+8282+```ocaml
8383+(* A simple function *)
8484+let add x y = x + y
8585+8686+(* With type annotations *)
8787+let add (x : int) (y : int) : int = x + y
8888+8989+(* Anonymous (lambda) function *)
9090+let increment = fun x -> x + 1
9191+9292+(* Partial application *)
9393+let add5 = add 5
9494+let fifteen = add5 10 (* equals 15 *)
9595+```
9696+9797+## Control Flow
9898+9999+OCaml uses expressions rather than statements for control flow:
100100+101101+```ocaml
102102+(* If expression *)
103103+let abs x =
104104+ if x < 0 then -x else x
105105+106106+(* Match expression (pattern matching) *)
107107+let describe_sign x =
108108+ match x with
109109+ | x when x < 0 -> "negative"
110110+ | 0 -> "zero"
111111+ | _ -> "positive"
112112+```
113113+114114+## Recursion
115115+116116+Functions need the `rec` keyword to be recursive:
117117+118118+```ocaml
119119+(* Recursive function *)
120120+let rec factorial n =
121121+ if n <= 1 then 1 else n * factorial (n - 1)
122122+123123+(* Mutually recursive functions *)
124124+let rec is_even n =
125125+ if n = 0 then true else is_odd (n - 1)
126126+and is_odd n =
127127+ if n = 0 then false else is_even (n - 1)
128128+```
129129+130130+This introduction to basic syntax sets the foundation for understanding OCaml's more advanced features, which we'll explore in the next chapters.
131131+|}
132132+ };
133133+ {
134134+ id = "chapter3";
135135+ title = "# Data Structures";
136136+ contents = {|
137137+# Data Structures
138138+139139+OCaml provides several built-in data structures and makes it easy to define custom ones.
140140+141141+## Tuples
142142+143143+Tuples are fixed-length collections of values that can have different types:
144144+145145+```ocaml
146146+(* A pair of an int and a string *)
147147+let person = (42, "Alice")
148148+149149+(* Extracting values with pattern matching *)
150150+let (age, name) = person
151151+152152+(* Accessing elements *)
153153+let age = fst person (* For pairs only *)
154154+let name = snd person (* For pairs only *)
155155+```
156156+157157+## Records
158158+159159+Records are named collections of values:
160160+161161+```ocaml
162162+(* Defining a record type *)
163163+type person = {
164164+ name: string;
165165+ age: int;
166166+ email: string option;
167167+}
168168+169169+(* Creating a record *)
170170+let alice = {
171171+ name = "Alice";
172172+ age = 42;
173173+ email = Some "alice@example.com";
174174+}
175175+176176+(* Accessing fields *)
177177+let alices_name = alice.name
178178+179179+(* Functional update (creates a new record) *)
180180+let alice_birthday = { alice with age = alice.age + 1 }
181181+```
182182+183183+## Variants
184184+185185+Variants (also called algebraic data types) represent values that can be one of several cases:
186186+187187+```ocaml
188188+(* Defining a variant type *)
189189+type shape =
190190+ | Circle of float (* radius *)
191191+ | Rectangle of float * float (* width, height *)
192192+ | Triangle of float * float * float (* sides *)
193193+194194+(* Creating variants *)
195195+let my_circle = Circle 2.5
196196+let my_rectangle = Rectangle (4.0, 6.0)
197197+198198+(* Pattern matching with variants *)
199199+let area shape =
200200+ match shape with
201201+ | Circle r -> Float.pi *. r *. r
202202+ | Rectangle (w, h) -> w *. h
203203+ | Triangle (a, b, c) ->
204204+ let s = (a +. b +. c) /. 2.0 in
205205+ sqrt (s *. (s -. a) *. (s -. b) *. (s -. c))
206206+```
207207+208208+## Lists
209209+210210+Lists are immutable linked lists of elements of the same type:
211211+212212+```ocaml
213213+(* Creating lists *)
214214+let empty = []
215215+let numbers = [1; 2; 3; 4; 5]
216216+let constructed = 1 :: 2 :: 3 :: []
217217+218218+(* Pattern matching with lists *)
219219+let rec sum_list lst =
220220+ match lst with
221221+ | [] -> 0
222222+ | head :: tail -> head + sum_list tail
223223+224224+(* Common list functions *)
225225+let doubled = List.map (fun x -> x * 2) numbers
226226+let evens = List.filter (fun x -> x mod 2 = 0) numbers
227227+let sum = List.fold_left (+) 0 numbers
228228+```
229229+230230+## Arrays
231231+232232+Arrays provide mutable, fixed-size collections with O(1) random access:
233233+234234+```ocaml
235235+(* Creating arrays *)
236236+let arr = [|1; 2; 3; 4; 5|]
237237+238238+(* Accessing elements (0-indexed) *)
239239+let first = arr.(0)
240240+241241+(* Modifying elements *)
242242+let () = arr.(0) <- 10
243243+244244+(* Array functions *)
245245+let doubled = Array.map (fun x -> x * 2) arr
246246+```
247247+248248+## Option Type
249249+250250+The option type represents values that might be absent:
251251+252252+```ocaml
253253+(* Option type *)
254254+type 'a option = None | Some of 'a
255255+256256+(* Using options *)
257257+let safe_divide x y =
258258+ if y = 0 then None else Some (x / y)
259259+260260+(* Working with options *)
261261+match safe_divide 10 2 with
262262+| None -> print_endline "Division by zero"
263263+| Some result -> Printf.printf "Result: %d\n" result
264264+```
265265+266266+These data structures form the backbone of OCaml programming and allow for expressing complex data relationships in a type-safe way.
267267+|}
268268+ };
269269+ {
270270+ id = "chapter4";
271271+ title = "# Modules and Functors";
272272+ contents = {|
273273+# Modules and Functors
274274+275275+OCaml's module system is one of its most powerful features. It allows for organizing code into reusable components with clear interfaces.
276276+277277+## Basic Modules
278278+279279+A module is a collection of related definitions (types, values, submodules, etc.):
280280+281281+```ocaml
282282+(* Defining a module *)
283283+module Math = struct
284284+ let pi = 3.14159
285285+ let square x = x *. x
286286+ let cube x = x *. x *. x
287287+end
288288+289289+(* Using a module *)
290290+let area_of_circle r = Math.pi *. Math.square r
291291+```
292292+293293+## Module Signatures
294294+295295+Module signatures define the interface of a module, hiding implementation details:
296296+297297+```ocaml
298298+(* Defining a signature *)
299299+module type MATH = sig
300300+ val pi : float
301301+ val square : float -> float
302302+ val cube : float -> float
303303+end
304304+305305+(* Implementing a signature *)
306306+module Math : MATH = struct
307307+ let pi = 3.14159
308308+ let square x = x *. x
309309+ let cube x = x *. x *. x
310310+311311+ (* This is hidden because it's not in the signature *)
312312+ let private_helper x = x +. 1.0
313313+end
314314+```
315315+316316+## Functors
317317+318318+Functors are functions from modules to modules, allowing for higher-order modularity:
319319+320320+```ocaml
321321+(* Module signature for collections *)
322322+module type COLLECTION = sig
323323+ type 'a t
324324+ val empty : 'a t
325325+ val add : 'a -> 'a t -> 'a t
326326+ val mem : 'a -> 'a t -> bool
327327+end
328328+329329+(* Functor that creates a set implementation given an element type with comparison *)
330330+module MakeSet (Element : sig type t val compare : t -> t -> int end) : COLLECTION with type 'a t = Element.t list = struct
331331+ type 'a t = Element.t list
332332+333333+ let empty = []
334334+335335+ let rec add x lst =
336336+ match lst with
337337+ | [] -> [x]
338338+ | y :: ys ->
339339+ let c = Element.compare x y in
340340+ if c < 0 then x :: lst
341341+ else if c = 0 then lst (* Element already exists *)
342342+ else y :: add x ys
343343+344344+ let rec mem x lst =
345345+ match lst with
346346+ | [] -> false
347347+ | y :: ys ->
348348+ let c = Element.compare x y in
349349+ if c = 0 then true
350350+ else if c < 0 then false
351351+ else mem x ys
352352+end
353353+354354+(* Creating an integer set *)
355355+module IntElement = struct
356356+ type t = int
357357+ let compare = Int.compare
358358+end
359359+360360+module IntSet = MakeSet(IntElement)
361361+362362+(* Using the set *)
363363+let my_set = IntSet.empty
364364+ |> IntSet.add 3
365365+ |> IntSet.add 1
366366+ |> IntSet.add 4
367367+ |> IntSet.add 1 (* Duplicate, not added *)
368368+369369+let has_three = IntSet.mem 3 my_set (* true *)
370370+let has_five = IntSet.mem 5 my_set (* false *)
371371+```
372372+373373+## First-Class Modules
374374+375375+OCaml also supports first-class modules, allowing modules to be passed as values:
376376+377377+```ocaml
378378+(* Module type for number operations *)
379379+module type NUMBER = sig
380380+ type t
381381+ val zero : t
382382+ val add : t -> t -> t
383383+ val to_string : t -> string
384384+end
385385+386386+(* Implementations for different number types *)
387387+module Int : NUMBER with type t = int = struct
388388+ type t = int
389389+ let zero = 0
390390+ let add = (+)
391391+ let to_string = string_of_int
392392+end
393393+394394+module Float : NUMBER with type t = float = struct
395395+ type t = float
396396+ let zero = 0.0
397397+ let add = (+.)
398398+ let to_string = string_of_float
399399+end
400400+401401+(* Function that works with any NUMBER module *)
402402+let sum_as_string (type a) (module N : NUMBER with type t = a) numbers =
403403+ let sum = List.fold_left N.add N.zero numbers in
404404+ N.to_string sum
405405+406406+(* Using first-class modules *)
407407+let int_sum = sum_as_string (module Int) [1; 2; 3; 4]
408408+let float_sum = sum_as_string (module Float) [1.0; 2.5; 3.7]
409409+```
410410+411411+## Open and Include
412412+413413+OCaml provides ways to bring module contents into scope:
414414+415415+```ocaml
416416+(* Open brings module contents into scope temporarily *)
417417+let area =
418418+ let open Math in
419419+ pi *. square 2.0
420420+421421+(* Local opening with the modern syntax *)
422422+let area = Math.(pi *. square 2.0)
423423+424424+(* Include actually extends a module with another module's contents *)
425425+module ExtendedMath = struct
426426+ include Math
427427+ let tau = 2.0 *. pi
428428+ let circumference r = tau *. r
429429+end
430430+```
431431+432432+The module system enables OCaml programmers to build highly modular, reusable code with clear boundaries between components.
433433+|}
434434+ };
435435+ {
436436+ id = "chapter5";
437437+ title = "# Advanced Features";
438438+ contents = {|
439439+# Advanced Features
440440+441441+OCaml offers several advanced features that set it apart from other languages. This chapter explores some of the more powerful language constructs.
442442+443443+## Polymorphic Variants
444444+445445+Unlike regular variants, polymorphic variants don't need to be predefined:
446446+447447+```ocaml
448448+(* Using polymorphic variants directly *)
449449+let weekend = `Saturday | `Sunday
450450+let is_weekend day =
451451+ match day with
452452+ | `Saturday | `Sunday -> true
453453+ | `Monday .. `Friday -> false
454454+455455+(* Can be used in mixed contexts *)
456456+let shape_area = function
457457+ | `Circle r -> Float.pi *. r *. r
458458+ | `Rectangle (w, h) -> w *. h
459459+ | `Triangle (b, h) -> 0.5 *. b *. h
460460+ | `Regular_polygon(n, s) when n >= 3 ->
461461+ let apothem = s /. (2.0 *. tan (Float.pi /. float_of_int n)) in
462462+ n *. s *. apothem /. 2.0
463463+ | _ -> failwith "Invalid shape"
464464+```
465465+466466+## Objects and Classes
467467+468468+OCaml supports object-oriented programming:
469469+470470+```ocaml
471471+(* Simple class definition *)
472472+class point x_init y_init =
473473+ object (self)
474474+ val mutable x = x_init
475475+ val mutable y = y_init
476476+477477+ method get_x = x
478478+ method get_y = y
479479+ method move dx dy = x <- x + dx; y <- y + dy
480480+ method distance_from_origin =
481481+ sqrt (float_of_int (x * x + y * y))
482482+483483+ (* Private method *)
484484+ method private to_string =
485485+ Printf.sprintf "(%d, %d)" x y
486486+487487+ (* Calling another method *)
488488+ method print = print_endline self#to_string
489489+ end
490490+491491+(* Using a class *)
492492+let p = new point 3 4
493493+let () = p#move 2 1
494494+let d = p#distance_from_origin
495495+```
496496+497497+## Generalized Algebraic Data Types (GADTs)
498498+499499+GADTs provide more type control than regular variants:
500500+501501+```ocaml
502502+(* A GADT for type-safe expressions *)
503503+type _ expr =
504504+ | Int : int -> int expr
505505+ | Bool : bool -> bool expr
506506+ | Add : int expr * int expr -> int expr
507507+ | Eq : 'a expr * 'a expr -> bool expr
508508+509509+(* Type-safe evaluation *)
510510+let rec eval : type a. a expr -> a = function
511511+ | Int n -> n
512512+ | Bool b -> b
513513+ | Add (e1, e2) -> eval e1 + eval e2
514514+ | Eq (e1, e2) -> eval e1 = eval e2
515515+516516+(* These expressions are statically type-checked *)
517517+let e1 = Add (Int 1, Int 2) (* OK: int expr *)
518518+let e2 = Eq (Int 1, Int 2) (* OK: bool expr *)
519519+(* let e3 = Add (Int 1, Bool true) (* Type error! *) *)
520520+(* let e4 = Eq (Int 1, Bool true) (* Type error! *) *)
521521+```
522522+523523+## Type Extensions
524524+525525+OCaml allows extending existing types:
526526+527527+```ocaml
528528+(* Original type *)
529529+type shape = Circle of float | Rectangle of float * float
530530+531531+(* Extending the type in another module *)
532532+type shape += Triangle of float * float * float
533533+534534+(* Pattern matching must now handle unknown cases *)
535535+let area = function
536536+ | Circle r -> Float.pi *. r *. r
537537+ | Rectangle (w, h) -> w *. h
538538+ | Triangle (a, b, c) ->
539539+ let s = (a +. b +. c) /. 2.0 in
540540+ sqrt (s *. (s -. a) *. (s -. b) *. (s -. c))
541541+ | _ -> failwith "Unknown shape"
542542+```
543543+544544+## Effects and Effect Handlers
545545+546546+OCaml 5 introduced algebraic effects for managing control flow:
547547+548548+```ocaml
549549+(* Defining an effect *)
550550+type _ Effect.t += Ask : string -> string Effect.t
551551+552552+(* Handler for the Ask effect *)
553553+let prompt_user () =
554554+ Effect.Deep.try_with
555555+ (fun () ->
556556+ let name = Effect.perform (Ask "What is your name?") in
557557+ Printf.printf "Hello, %s!\n" name)
558558+ { Effect.Deep.effc = fun (type a) (effect : a Effect.t) ->
559559+ match effect with
560560+ | Ask prompt -> fun k ->
561561+ Printf.printf "%s " prompt;
562562+ let response = read_line () in
563563+ k response
564564+ | _ -> None }
565565+```
566566+567567+## Higher-Ranked Polymorphism
568568+569569+Using the `Obj.magic` escape hatch (with caution):
570570+571571+```ocaml
572572+(* This would normally not be permitted due to rank-2 polymorphism *)
573573+let apply_to_all_types f =
574574+ let magic_f : 'a -> string = Obj.magic f in
575575+ [
576576+ magic_f 42;
577577+ magic_f "hello";
578578+ magic_f 3.14;
579579+ magic_f true;
580580+ ]
581581+582582+(* Usage - with great care! *)
583583+let result = apply_to_all_types (fun x -> Printf.sprintf "Value: %s" (Obj.magic x))
584584+```
585585+586586+## Metaprogramming with PPX
587587+588588+OCaml's PPX system enables powerful metaprogramming:
589589+590590+```ocaml
591591+(* With ppx_deriving *)
592592+type person = {
593593+ name: string;
594594+ age: int;
595595+ email: string option;
596596+} [@@deriving show, eq, ord]
597597+598598+(* With ppx_sexp_conv *)
599599+type config = {
600600+ server: string;
601601+ port: int;
602602+ timeout: float;
603603+} [@@deriving sexp]
604604+605605+(* With ppx_let for monadic operations *)
606606+let computation =
607607+ [%m.let
608608+ let* x = get_value_from_db "key1" in
609609+ let* y = get_value_from_db "key2" in
610610+ return (x + y)
611611+ ]
612612+```
613613+614614+## Modules for Advanced Typing
615615+616616+Using modules to encode complex type relationships:
617617+618618+```ocaml
619619+(* Phantom types for added type safety *)
620620+module SafeString : sig
621621+ type 'a t
622622+623623+ (* Constructors for different string types *)
624624+ val of_raw : string -> [`Raw] t
625625+ val sanitize : [`Raw] t -> [`Sanitized] t
626626+ val validate : [`Sanitized] t -> [`Validated] t option
627627+628628+ (* Operations that require specific string types *)
629629+ val to_html : [`Sanitized] t -> string
630630+ val to_sql : [`Validated] t -> string
631631+632632+ (* Common operations for all string types *)
633633+ val length : _ t -> int
634634+ val concat : _ t -> _ t -> [`Raw] t
635635+end = struct
636636+ type 'a t = string
637637+638638+ let of_raw s = s
639639+ let sanitize s = String.map (function '<' | '>' -> '_' | c -> c) s
640640+ let validate s = if String.length s > 0 then Some s else None
641641+642642+ let to_html s = s
643643+ let to_sql s = "'" ^ String.map (function '\'' -> '\'' | c -> c) s ^ "'"
644644+645645+ let length = String.length
646646+ let concat s1 s2 = s1 ^ s2
647647+end
648648+```
649649+650650+These advanced features make OCaml a uniquely powerful language for expressing complex programs with strong guarantees about correctness.
651651+|}
652652+ };
653653+ ]
654654+655655+ (* Get a chapter by ID *)
656656+ let get_by_id id =
657657+ try Some (List.find (fun c -> c.id = id) chapters)
658658+ with Not_found -> None
659659+660660+ (* Get chapter titles *)
661661+ let get_all_titles () =
662662+ List.map (fun c -> (c.id, c.title)) chapters
663663+end
664664+665665+(* Create a server *)
666666+let server = create_server
667667+ ~name:"OCaml MCP Book Resource Example"
668668+ ~version:"0.1.0" () |>
669669+ fun server ->
670670+ (* Set default capabilities *)
671671+ configure_server server
672672+ ~with_tools:false
673673+ ~with_resources:true
674674+ ~with_resource_templates:true
675675+ ~with_prompts:false ()
676676+677677+(* Add a resource template to get book chapters *)
678678+let _ = add_resource_template server
679679+ ~uri_template:"book/chapter/{id}"
680680+ ~name:"Chapter Resource"
681681+ ~description:"Get a specific chapter from the OCaml book by its ID"
682682+ ~mime_type:"text/markdown"
683683+ (fun params ->
684684+ match params with
685685+ | [id] ->
686686+ (match BookChapter.get_by_id id with
687687+ | Some chapter -> chapter.contents
688688+ | None -> Printf.sprintf "# Error\n\nChapter with ID '%s' not found." id)
689689+ | _ -> "# Error\n\nInvalid parameters. Expected chapter ID."
690690+ )
691691+692692+(* Add a regular resource to get table of contents (no variables) *)
693693+let _ = add_resource server
694694+ ~uri:"book/toc"
695695+ ~name:"Table of Contents"
696696+ ~description:"Get the table of contents for the OCaml book"
697697+ ~mime_type:"text/markdown"
698698+ (fun _params ->
699699+ let titles = BookChapter.get_all_titles() in
700700+ let toc = "# OCaml Book - Table of Contents\n\n" ^
701701+ (List.mapi (fun i (id, title) ->
702702+ Printf.sprintf "%d. [%s](book/chapter/%s)\n"
703703+ (i + 1)
704704+ (String.sub title 2 (String.length title - 2)) (* Remove "# " prefix *)
705705+ id
706706+ ) titles |> String.concat "")
707707+ in
708708+ toc
709709+ )
710710+711711+(* Add a regular resource for a complete book (no variables) *)
712712+let _ = add_resource server
713713+ ~uri:"book/complete"
714714+ ~name:"Full contents"
715715+ ~description:"Get the complete OCaml book as a single document"
716716+ ~mime_type:"text/markdown"
717717+ (fun _params ->
718718+ let chapter_contents = List.map (fun c -> c.BookChapter.contents) BookChapter.chapters in
719719+ let content = "# The OCaml Book\n\n*A comprehensive guide to OCaml programming*\n\n" ^
720720+ (String.concat "\n\n---\n\n" chapter_contents)
721721+ in
722722+ content
723723+ )
724724+725725+(* Run the server with the default scheduler *)
726726+let () =
727727+ Eio_main.run @@ fun env ->
728728+ Mcp_server.run_server env server