Model Context Protocol in OCaml
1(* Mcp_message - High-level RPC message definitions for Model Context Protocol *) 2 3open Mcp 4open Jsonrpc 5 6(* Resources/List *) 7module ResourcesList = struct 8 module Request = struct 9 type t = { cursor : Cursor.t option } 10 11 let yojson_of_t { cursor } = 12 let assoc = [] in 13 let assoc = 14 match cursor with 15 | Some c -> ("cursor", Cursor.yojson_of_t c) :: assoc 16 | None -> assoc 17 in 18 `Assoc assoc 19 20 let t_of_yojson = function 21 | `Assoc fields -> 22 let cursor = 23 List.assoc_opt "cursor" fields |> Option.map Cursor.t_of_yojson 24 in 25 { cursor } 26 | j -> Util.json_error "Expected object for ResourcesList.Request.t" j 27 end 28 29 module Resource = struct 30 type t = { 31 uri : string; 32 name : string; 33 description : string option; 34 mime_type : string option; 35 size : int option; 36 } 37 38 let yojson_of_t { uri; name; description; mime_type; size } = 39 let assoc = [ ("uri", `String uri); ("name", `String name) ] in 40 let assoc = 41 match description with 42 | Some desc -> ("description", `String desc) :: assoc 43 | None -> assoc 44 in 45 let assoc = 46 match mime_type with 47 | Some mime -> ("mimeType", `String mime) :: assoc 48 | None -> assoc 49 in 50 let assoc = 51 match size with Some s -> ("size", `Int s) :: assoc | None -> assoc 52 in 53 `Assoc assoc 54 55 let t_of_yojson = function 56 | `Assoc fields as json -> 57 let uri = 58 match List.assoc_opt "uri" fields with 59 | Some (`String s) -> s 60 | _ -> Util.json_error "Missing or invalid 'uri' field" json 61 in 62 let name = 63 match List.assoc_opt "name" fields with 64 | Some (`String s) -> s 65 | _ -> Util.json_error "Missing or invalid 'name' field" json 66 in 67 let description = 68 List.assoc_opt "description" fields 69 |> Option.map (function 70 | `String s -> s 71 | j -> Util.json_error "Expected string for description" j) 72 in 73 let mime_type = 74 List.assoc_opt "mimeType" fields 75 |> Option.map (function 76 | `String s -> s 77 | j -> Util.json_error "Expected string for mimeType" j) 78 in 79 let size = 80 List.assoc_opt "size" fields 81 |> Option.map (function 82 | `Int i -> i 83 | j -> Util.json_error "Expected int for size" j) 84 in 85 { uri; name; description; mime_type; size } 86 | j -> Util.json_error "Expected object for ResourcesList.Resource.t" j 87 end 88 89 module Response = struct 90 type t = { resources : Resource.t list; next_cursor : Cursor.t option } 91 92 let yojson_of_t { resources; next_cursor } = 93 let assoc = 94 [ ("resources", `List (List.map Resource.yojson_of_t resources)) ] 95 in 96 let assoc = 97 match next_cursor with 98 | Some c -> ("nextCursor", Cursor.yojson_of_t c) :: assoc 99 | None -> assoc 100 in 101 `Assoc assoc 102 103 let t_of_yojson = function 104 | `Assoc fields as json -> 105 let resources = 106 match List.assoc_opt "resources" fields with 107 | Some (`List items) -> List.map Resource.t_of_yojson items 108 | _ -> Util.json_error "Missing or invalid 'resources' field" json 109 in 110 let next_cursor = 111 List.assoc_opt "nextCursor" fields |> Option.map Cursor.t_of_yojson 112 in 113 { resources; next_cursor } 114 | j -> Util.json_error "Expected object for ResourcesList.Response.t" j 115 end 116 117 (* Request/response creation helpers *) 118 let create_request ?cursor ?id () = 119 let id = match id with Some i -> i | None -> `Int (Random.int 10000) in 120 let params = Request.yojson_of_t { cursor } in 121 JSONRPCMessage.create_request ~id ~meth:Method.ResourcesList 122 ~params:(Some params) () 123 124 let create_response ~id ~resources ?next_cursor () = 125 let result = Response.yojson_of_t { resources; next_cursor } in 126 JSONRPCMessage.create_response ~id ~result 127end 128 129(* Resources/Templates/List *) 130module ListResourceTemplatesRequest = struct 131 type t = { cursor : Cursor.t option } 132 133 let yojson_of_t { cursor } = 134 let assoc = [] in 135 let assoc = 136 match cursor with 137 | Some c -> ("cursor", Cursor.yojson_of_t c) :: assoc 138 | None -> assoc 139 in 140 `Assoc assoc 141 142 let t_of_yojson = function 143 | `Assoc fields -> 144 let cursor = 145 List.assoc_opt "cursor" fields |> Option.map Cursor.t_of_yojson 146 in 147 { cursor } 148 | j -> 149 Util.json_error "Expected object for ListResourceTemplatesRequest.t" j 150end 151 152(* Resources/Templates/List Response *) 153module ListResourceTemplatesResult = struct 154 module ResourceTemplate = struct 155 type t = { 156 uri_template : string; 157 name : string; 158 description : string option; 159 mime_type : string option; 160 } 161 162 let yojson_of_t { uri_template; name; description; mime_type } = 163 let assoc = 164 [ ("uriTemplate", `String uri_template); ("name", `String name) ] 165 in 166 let assoc = 167 match description with 168 | Some desc -> ("description", `String desc) :: assoc 169 | None -> assoc 170 in 171 let assoc = 172 match mime_type with 173 | Some mime -> ("mimeType", `String mime) :: assoc 174 | None -> assoc 175 in 176 `Assoc assoc 177 178 let t_of_yojson = function 179 | `Assoc fields as json -> 180 let uri_template = 181 match List.assoc_opt "uriTemplate" fields with 182 | Some (`String s) -> s 183 | _ -> Util.json_error "Missing or invalid 'uriTemplate' field" json 184 in 185 let name = 186 match List.assoc_opt "name" fields with 187 | Some (`String s) -> s 188 | _ -> Util.json_error "Missing or invalid 'name' field" json 189 in 190 let description = 191 List.assoc_opt "description" fields 192 |> Option.map (function 193 | `String s -> s 194 | j -> Util.json_error "Expected string for description" j) 195 in 196 let mime_type = 197 List.assoc_opt "mimeType" fields 198 |> Option.map (function 199 | `String s -> s 200 | j -> Util.json_error "Expected string for mimeType" j) 201 in 202 { uri_template; name; description; mime_type } 203 | j -> 204 Util.json_error 205 "Expected object for ListResourceTemplatesResult.ResourceTemplate.t" 206 j 207 end 208 209 type t = { 210 resource_templates : ResourceTemplate.t list; 211 next_cursor : Cursor.t option; 212 } 213 214 let yojson_of_t { resource_templates; next_cursor } = 215 let assoc = 216 [ 217 ( "resourceTemplates", 218 `List (List.map ResourceTemplate.yojson_of_t resource_templates) ); 219 ] 220 in 221 let assoc = 222 match next_cursor with 223 | Some c -> ("nextCursor", Cursor.yojson_of_t c) :: assoc 224 | None -> assoc 225 in 226 `Assoc assoc 227 228 let t_of_yojson = function 229 | `Assoc fields as json -> 230 let resource_templates = 231 match List.assoc_opt "resourceTemplates" fields with 232 | Some (`List items) -> List.map ResourceTemplate.t_of_yojson items 233 | _ -> 234 Util.json_error "Missing or invalid 'resourceTemplates' field" 235 json 236 in 237 let next_cursor = 238 List.assoc_opt "nextCursor" fields |> Option.map Cursor.t_of_yojson 239 in 240 { resource_templates; next_cursor } 241 | j -> Util.json_error "Expected object for ListResourceTemplatesResult.t" j 242 243 (* Request/response creation helpers *) 244 let create_request ?cursor ?id () = 245 let id = match id with Some i -> i | None -> `Int (Random.int 10000) in 246 let params = ListResourceTemplatesRequest.yojson_of_t { cursor } in 247 JSONRPCMessage.create_request ~id ~meth:Method.ResourceTemplatesList 248 ~params:(Some params) () 249 250 let create_response ~id ~resource_templates ?next_cursor () = 251 let result = yojson_of_t { resource_templates; next_cursor } in 252 JSONRPCMessage.create_response ~id ~result 253end 254 255(* Resources/Read *) 256module ResourcesRead = struct 257 module Request = struct 258 type t = { uri : string } 259 260 let yojson_of_t { uri } = `Assoc [ ("uri", `String uri) ] 261 262 let t_of_yojson = function 263 | `Assoc fields as json -> 264 let uri = 265 match List.assoc_opt "uri" fields with 266 | Some (`String s) -> s 267 | _ -> Util.json_error "Missing or invalid 'uri' field" json 268 in 269 { uri } 270 | j -> Util.json_error "Expected object for ResourcesRead.Request.t" j 271 end 272 273 module ResourceContent = struct 274 type t = 275 | TextResource of TextResourceContents.t 276 | BlobResource of BlobResourceContents.t 277 278 let yojson_of_t = function 279 | TextResource tr -> TextResourceContents.yojson_of_t tr 280 | BlobResource br -> BlobResourceContents.yojson_of_t br 281 282 let t_of_yojson json = 283 match json with 284 | `Assoc fields -> 285 if List.mem_assoc "text" fields then 286 TextResource (TextResourceContents.t_of_yojson json) 287 else if List.mem_assoc "blob" fields then 288 BlobResource (BlobResourceContents.t_of_yojson json) 289 else Util.json_error "Invalid resource content" json 290 | j -> 291 Util.json_error "Expected object for ResourcesRead.ResourceContent.t" 292 j 293 end 294 295 module Response = struct 296 type t = { contents : ResourceContent.t list } 297 298 let yojson_of_t { contents } = 299 `Assoc 300 [ ("contents", `List (List.map ResourceContent.yojson_of_t contents)) ] 301 302 let t_of_yojson = function 303 | `Assoc fields as json -> 304 let contents = 305 match List.assoc_opt "contents" fields with 306 | Some (`List items) -> List.map ResourceContent.t_of_yojson items 307 | _ -> Util.json_error "Missing or invalid 'contents' field" json 308 in 309 { contents } 310 | j -> Util.json_error "Expected object for ResourcesRead.Response.t" j 311 end 312 313 (* Request/response creation helpers *) 314 let create_request ~uri ?id () = 315 let id = match id with Some i -> i | None -> `Int (Random.int 10000) in 316 let params = Request.yojson_of_t { uri } in 317 JSONRPCMessage.create_request ~id ~meth:Method.ResourcesRead 318 ~params:(Some params) () 319 320 let create_response ~id ~contents () = 321 let result = Response.yojson_of_t { contents } in 322 JSONRPCMessage.create_response ~id ~result 323end 324 325(* Tools/List *) 326module ToolsList = struct 327 module Request = struct 328 type t = { cursor : Cursor.t option } 329 330 let yojson_of_t { cursor } = 331 let assoc = [] in 332 let assoc = 333 match cursor with 334 | Some c -> ("cursor", Cursor.yojson_of_t c) :: assoc 335 | None -> assoc 336 in 337 `Assoc assoc 338 339 let t_of_yojson = function 340 | `Assoc fields -> 341 let cursor = 342 List.assoc_opt "cursor" fields |> Option.map Cursor.t_of_yojson 343 in 344 { cursor } 345 | j -> Util.json_error "Expected object for ToolsList.Request.t" j 346 end 347 348 module Tool = struct 349 type t = { 350 name : string; 351 description : string option; 352 input_schema : Json.t; 353 annotations : Json.t option; 354 } 355 356 let yojson_of_t { name; description; input_schema; annotations } = 357 let assoc = [ ("name", `String name); ("inputSchema", input_schema) ] in 358 let assoc = 359 match description with 360 | Some desc -> ("description", `String desc) :: assoc 361 | None -> assoc 362 in 363 let assoc = 364 match annotations with 365 | Some anno -> ("annotations", anno) :: assoc 366 | None -> assoc 367 in 368 `Assoc assoc 369 370 let t_of_yojson = function 371 | `Assoc fields as json -> 372 let name = 373 match List.assoc_opt "name" fields with 374 | Some (`String s) -> s 375 | _ -> Util.json_error "Missing or invalid 'name' field" json 376 in 377 let description = 378 List.assoc_opt "description" fields 379 |> Option.map (function 380 | `String s -> s 381 | j -> Util.json_error "Expected string for description" j) 382 in 383 let input_schema = 384 match List.assoc_opt "inputSchema" fields with 385 | Some schema -> schema 386 | None -> Util.json_error "Missing 'inputSchema' field" json 387 in 388 let annotations = List.assoc_opt "annotations" fields in 389 { name; description; input_schema; annotations } 390 | j -> Util.json_error "Expected object for ToolsList.Tool.t" j 391 end 392 393 module Response = struct 394 type t = { tools : Tool.t list; next_cursor : Cursor.t option } 395 396 let yojson_of_t { tools; next_cursor } = 397 let assoc = [ ("tools", `List (List.map Tool.yojson_of_t tools)) ] in 398 let assoc = 399 match next_cursor with 400 | Some c -> ("nextCursor", Cursor.yojson_of_t c) :: assoc 401 | None -> assoc 402 in 403 `Assoc assoc 404 405 let t_of_yojson = function 406 | `Assoc fields as json -> 407 let tools = 408 match List.assoc_opt "tools" fields with 409 | Some (`List items) -> List.map Tool.t_of_yojson items 410 | _ -> Util.json_error "Missing or invalid 'tools' field" json 411 in 412 let next_cursor = 413 List.assoc_opt "nextCursor" fields |> Option.map Cursor.t_of_yojson 414 in 415 { tools; next_cursor } 416 | j -> Util.json_error "Expected object for ToolsList.Response.t" j 417 end 418 419 (* Request/response creation helpers *) 420 let create_request ?cursor ?id () = 421 let id = match id with Some i -> i | None -> `Int (Random.int 10000) in 422 let params = Request.yojson_of_t { cursor } in 423 JSONRPCMessage.create_request ~id ~meth:Method.ToolsList 424 ~params:(Some params) () 425 426 let create_response ~id ~tools ?next_cursor () = 427 let result = Response.yojson_of_t { tools; next_cursor } in 428 JSONRPCMessage.create_response ~id ~result 429end 430 431(* Tools/Call *) 432module ToolsCall = struct 433 module Request = struct 434 type t = { name : string; arguments : Json.t } 435 436 let yojson_of_t { name; arguments } = 437 `Assoc [ ("name", `String name); ("arguments", arguments) ] 438 439 let t_of_yojson = function 440 | `Assoc fields as json -> 441 let name = 442 match List.assoc_opt "name" fields with 443 | Some (`String s) -> s 444 | _ -> Util.json_error "Missing or invalid 'name' field" json 445 in 446 let arguments = 447 match List.assoc_opt "arguments" fields with 448 | Some json -> json 449 | None -> Util.json_error "Missing 'arguments' field" json 450 in 451 { name; arguments } 452 | j -> Util.json_error "Expected object for ToolsCall.Request.t" j 453 end 454 455 module ToolContent = struct 456 type t = 457 | Text of TextContent.t 458 | Image of ImageContent.t 459 | Audio of AudioContent.t 460 | Resource of EmbeddedResource.t 461 462 let yojson_of_t = function 463 | Text t -> TextContent.yojson_of_t t 464 | Image i -> ImageContent.yojson_of_t i 465 | Audio a -> AudioContent.yojson_of_t a 466 | Resource r -> EmbeddedResource.yojson_of_t r 467 468 let t_of_yojson json = 469 match json with 470 | `Assoc fields -> ( 471 match List.assoc_opt "type" fields with 472 | Some (`String "text") -> Text (TextContent.t_of_yojson json) 473 | Some (`String "image") -> Image (ImageContent.t_of_yojson json) 474 | Some (`String "audio") -> Audio (AudioContent.t_of_yojson json) 475 | Some (`String "resource") -> 476 Resource (EmbeddedResource.t_of_yojson json) 477 | _ -> Util.json_error "Invalid or missing content type" json) 478 | j -> Util.json_error "Expected object for ToolsCall.ToolContent.t" j 479 end 480 481 module Response = struct 482 type t = { content : ToolContent.t list; is_error : bool } 483 484 let yojson_of_t { content; is_error } = 485 `Assoc 486 [ 487 ("content", `List (List.map ToolContent.yojson_of_t content)); 488 ("isError", `Bool is_error); 489 ] 490 491 let t_of_yojson = function 492 | `Assoc fields as json -> 493 let content = 494 match List.assoc_opt "content" fields with 495 | Some (`List items) -> List.map ToolContent.t_of_yojson items 496 | _ -> Util.json_error "Missing or invalid 'content' field" json 497 in 498 let is_error = 499 match List.assoc_opt "isError" fields with 500 | Some (`Bool b) -> b 501 | _ -> false 502 in 503 { content; is_error } 504 | j -> Util.json_error "Expected object for ToolsCall.Response.t" j 505 end 506 507 (* Request/response creation helpers *) 508 let create_request ~name ~arguments ?id () = 509 let id = match id with Some i -> i | None -> `Int (Random.int 10000) in 510 let params = Request.yojson_of_t { name; arguments } in 511 JSONRPCMessage.create_request ~id ~meth:Method.ToolsCall 512 ~params:(Some params) () 513 514 let create_response ~id ~content ~is_error () = 515 let result = Response.yojson_of_t { content; is_error } in 516 JSONRPCMessage.create_response ~id ~result 517end 518 519(* Prompts/List *) 520module PromptsList = struct 521 module PromptArgument = struct 522 type t = { name : string; description : string option; required : bool } 523 524 let yojson_of_t { name; description; required } = 525 let assoc = [ ("name", `String name) ] in 526 let assoc = 527 match description with 528 | Some desc -> ("description", `String desc) :: assoc 529 | None -> assoc 530 in 531 let assoc = 532 if required then ("required", `Bool true) :: assoc else assoc 533 in 534 `Assoc assoc 535 536 let t_of_yojson = function 537 | `Assoc fields as json -> 538 let name = 539 match List.assoc_opt "name" fields with 540 | Some (`String s) -> s 541 | _ -> Util.json_error "Missing or invalid 'name' field" json 542 in 543 let description = 544 List.assoc_opt "description" fields 545 |> Option.map (function 546 | `String s -> s 547 | j -> Util.json_error "Expected string for description" j) 548 in 549 let required = 550 match List.assoc_opt "required" fields with 551 | Some (`Bool b) -> b 552 | _ -> false 553 in 554 { name; description; required } 555 | j -> 556 Util.json_error "Expected object for PromptsList.PromptArgument.t" j 557 end 558 559 module Prompt = struct 560 type t = { 561 name : string; 562 description : string option; 563 arguments : PromptArgument.t list; 564 } 565 566 let yojson_of_t { name; description; arguments } = 567 let assoc = [ ("name", `String name) ] in 568 let assoc = 569 match description with 570 | Some desc -> ("description", `String desc) :: assoc 571 | None -> assoc 572 in 573 let assoc = 574 if arguments <> [] then 575 ("arguments", `List (List.map PromptArgument.yojson_of_t arguments)) 576 :: assoc 577 else assoc 578 in 579 `Assoc assoc 580 581 let t_of_yojson = function 582 | `Assoc fields as json -> 583 let name = 584 match List.assoc_opt "name" fields with 585 | Some (`String s) -> s 586 | _ -> Util.json_error "Missing or invalid 'name' field" json 587 in 588 let description = 589 List.assoc_opt "description" fields 590 |> Option.map (function 591 | `String s -> s 592 | j -> Util.json_error "Expected string for description" j) 593 in 594 let arguments = 595 match List.assoc_opt "arguments" fields with 596 | Some (`List items) -> List.map PromptArgument.t_of_yojson items 597 | _ -> [] 598 in 599 { name; description; arguments } 600 | j -> Util.json_error "Expected object for PromptsList.Prompt.t" j 601 end 602 603 module Request = struct 604 type t = { cursor : Cursor.t option } 605 606 let yojson_of_t { cursor } = 607 let assoc = [] in 608 let assoc = 609 match cursor with 610 | Some c -> ("cursor", Cursor.yojson_of_t c) :: assoc 611 | None -> assoc 612 in 613 `Assoc assoc 614 615 let t_of_yojson = function 616 | `Assoc fields -> 617 let cursor = 618 List.assoc_opt "cursor" fields |> Option.map Cursor.t_of_yojson 619 in 620 { cursor } 621 | j -> Util.json_error "Expected object for PromptsList.Request.t" j 622 end 623 624 module Response = struct 625 type t = { prompts : Prompt.t list; next_cursor : Cursor.t option } 626 627 let yojson_of_t { prompts; next_cursor } = 628 let assoc = 629 [ ("prompts", `List (List.map Prompt.yojson_of_t prompts)) ] 630 in 631 let assoc = 632 match next_cursor with 633 | Some c -> ("nextCursor", Cursor.yojson_of_t c) :: assoc 634 | None -> assoc 635 in 636 `Assoc assoc 637 638 let t_of_yojson = function 639 | `Assoc fields as json -> 640 let prompts = 641 match List.assoc_opt "prompts" fields with 642 | Some (`List items) -> List.map Prompt.t_of_yojson items 643 | _ -> Util.json_error "Missing or invalid 'prompts' field" json 644 in 645 let next_cursor = 646 List.assoc_opt "nextCursor" fields |> Option.map Cursor.t_of_yojson 647 in 648 { prompts; next_cursor } 649 | j -> Util.json_error "Expected object for PromptsList.Response.t" j 650 end 651 652 (* Request/response creation helpers *) 653 let create_request ?cursor ?id () = 654 let id = match id with Some i -> i | None -> `Int (Random.int 10000) in 655 let params = Request.yojson_of_t { cursor } in 656 JSONRPCMessage.create_request ~id ~meth:Method.PromptsList 657 ~params:(Some params) () 658 659 let create_response ~id ~prompts ?next_cursor () = 660 let result = Response.yojson_of_t { prompts; next_cursor } in 661 JSONRPCMessage.create_response ~id ~result 662end 663 664(* Prompts/Get *) 665module PromptsGet = struct 666 module Request = struct 667 type t = { name : string; arguments : (string * string) list } 668 669 let yojson_of_t { name; arguments } = 670 let args_json = 671 `Assoc (List.map (fun (k, v) -> (k, `String v)) arguments) 672 in 673 `Assoc [ ("name", `String name); ("arguments", args_json) ] 674 675 let t_of_yojson = function 676 | `Assoc fields as json -> 677 let name = 678 match List.assoc_opt "name" fields with 679 | Some (`String s) -> s 680 | _ -> Util.json_error "Missing or invalid 'name' field" json 681 in 682 let arguments = 683 match List.assoc_opt "arguments" fields with 684 | Some (`Assoc args) -> 685 List.map 686 (fun (k, v) -> 687 match v with 688 | `String s -> (k, s) 689 | _ -> 690 Util.json_error "Expected string value for argument" v) 691 args 692 | _ -> [] 693 in 694 { name; arguments } 695 | j -> Util.json_error "Expected object for PromptsGet.Request.t" j 696 end 697 698 module Response = struct 699 type t = { description : string option; messages : PromptMessage.t list } 700 701 let yojson_of_t { description; messages } = 702 let assoc = 703 [ ("messages", `List (List.map PromptMessage.yojson_of_t messages)) ] 704 in 705 let assoc = 706 match description with 707 | Some desc -> ("description", `String desc) :: assoc 708 | None -> assoc 709 in 710 `Assoc assoc 711 712 let t_of_yojson = function 713 | `Assoc fields as json -> 714 let messages = 715 match List.assoc_opt "messages" fields with 716 | Some (`List items) -> List.map PromptMessage.t_of_yojson items 717 | _ -> Util.json_error "Missing or invalid 'messages' field" json 718 in 719 let description = 720 List.assoc_opt "description" fields 721 |> Option.map (function 722 | `String s -> s 723 | j -> Util.json_error "Expected string for description" j) 724 in 725 { description; messages } 726 | j -> Util.json_error "Expected object for PromptsGet.Response.t" j 727 end 728 729 (* Request/response creation helpers *) 730 let create_request ~name ~arguments ?id () = 731 let id = match id with Some i -> i | None -> `Int (Random.int 10000) in 732 let params = Request.yojson_of_t { name; arguments } in 733 JSONRPCMessage.create_request ~id ~meth:Method.PromptsGet 734 ~params:(Some params) () 735 736 let create_response ~id ?description ~messages () = 737 let result = Response.yojson_of_t { description; messages } in 738 JSONRPCMessage.create_response ~id ~result 739end 740 741(* List Changed Notifications *) 742module ListChanged = struct 743 (* No parameters for these notifications *) 744 745 let create_resources_notification () = 746 JSONRPCMessage.create_notification ~meth:Method.ResourcesListChanged () 747 748 let create_tools_notification () = 749 JSONRPCMessage.create_notification ~meth:Method.ToolsListChanged () 750 751 let create_prompts_notification () = 752 JSONRPCMessage.create_notification ~meth:Method.PromptsListChanged () 753end 754 755(* Resource Updated Notification *) 756module ResourceUpdated = struct 757 module Notification = struct 758 type t = { uri : string } 759 760 let yojson_of_t { uri } = `Assoc [ ("uri", `String uri) ] 761 762 let t_of_yojson = function 763 | `Assoc fields as json -> 764 let uri = 765 match List.assoc_opt "uri" fields with 766 | Some (`String s) -> s 767 | _ -> Util.json_error "Missing or invalid 'uri' field" json 768 in 769 { uri } 770 | j -> 771 Util.json_error "Expected object for ResourceUpdated.Notification.t" j 772 end 773 774 let create_notification ~uri () = 775 let params = Notification.yojson_of_t { uri } in 776 JSONRPCMessage.create_notification ~meth:Method.ResourcesUpdated 777 ~params:(Some params) () 778end 779 780(* Progress Notification *) 781module Progress = struct 782 module Notification = struct 783 type t = { 784 progress : float; 785 total : float; 786 progress_token : ProgressToken.t; 787 } 788 789 let yojson_of_t { progress; total; progress_token } = 790 `Assoc 791 [ 792 ("progress", `Float progress); 793 ("total", `Float total); 794 ("progressToken", ProgressToken.yojson_of_t progress_token); 795 ] 796 797 let t_of_yojson = function 798 | `Assoc fields as json -> 799 let progress = 800 match List.assoc_opt "progress" fields with 801 | Some (`Float f) -> f 802 | _ -> Util.json_error "Missing or invalid 'progress' field" json 803 in 804 let total = 805 match List.assoc_opt "total" fields with 806 | Some (`Float f) -> f 807 | _ -> Util.json_error "Missing or invalid 'total' field" json 808 in 809 let progress_token = 810 match List.assoc_opt "progressToken" fields with 811 | Some token -> ProgressToken.t_of_yojson token 812 | _ -> 813 Util.json_error "Missing or invalid 'progressToken' field" json 814 in 815 { progress; total; progress_token } 816 | j -> Util.json_error "Expected object for Progress.Notification.t" j 817 end 818 819 let create_notification ~progress ~total ~progress_token () = 820 let params = Notification.yojson_of_t { progress; total; progress_token } in 821 JSONRPCMessage.create_notification ~meth:Method.Progress 822 ~params:(Some params) () 823end 824 825(* Type aliases for backward compatibility *) 826type request = ResourcesList.Request.t 827type response = ResourcesList.Response.t 828type resource = ResourcesList.Resource.t 829type resource_content = ResourcesRead.ResourceContent.t 830type tool = ToolsList.Tool.t 831type tool_content = ToolsCall.ToolContent.t 832type prompt = PromptsList.Prompt.t 833type prompt_argument = PromptsList.PromptArgument.t